如何在不插入的情况下更新Django模型?

时间:2012-07-20 13:28:25

标签: django modelform updatemodel

我的Django代码插入新行而不是更新现有行时出现问题。这里的很多人都在寻求类似问题的帮助,但通常他们忘记了在instance中设置form = SomeModelForm(request.POST or None, instance=some_model_instance)。我似乎做得对,但它仍然无法保存现有数据。

另一张海报有完全相同的问题(见Django form INSERTs when I want it to UPDATE)。看起来给他修复问题的代码解决了这个问题,但没有人解释为什么它在他问的时候有效!

查看

   if form_type == "edit_event":
        # we need to load all the data based on the event_id
        event_id = request.POST['event_id'] or None
        event_to_edit = mapDataManager.getEvent(event_id)
        if event_to_edit and mapDataManager.userCreatedEvent(request.user, event_to_edit):
            # this user actually created this event
            # let them edit it
            event_form = EventModelForm(request.POST or None, instance=event_to_edit)
            location_form = LocationModelForm(request.POST or None, instance=event_to_edit.location)
            list_of_event_scheds = EventSchedule.objects.filter(pk=event_id).values()
            event_sched_formset = EventScheduleModelFormSet(request.POST or None, initial=list_of_event_scheds)

            if event_form and location_form and event_sched_formset:
                if event_form.is_valid() and location_form.is_valid() and event_sched_formset.is_valid():
                    # update event
                    mapDataManager.updateEvent(event_form, location_form, event_sched_formset)
                    # redirect
                    return HttpResponseRedirect(reverse('map'))
                else:
                    # set feedback to show edit event form
                    feedback = "edit_event"

updateEvent()

def updateEvent(self, event_form, location_form, event_sched_forms):

    event = event_form.save(commit=False)
    location = location_form.save()
    event.location = location
    event.save()
    for event_sched_form in event_sched_forms: # loop through formset
        event_sched = event_sched_form.save(commit=False)
        event_sched.event = event
        event_sched.save()

任何人都可以帮助我吗?我错过了一些非常基本的东西吗?

编辑:只是为了澄清,我的表单没有更新,都插入了。基于Daniel的建议,我认为我需要使用formsets来链接正在编辑的所有三个模型。

3 个答案:

答案 0 :(得分:1)

由于某些奇怪的原因,您正确地将instance传递给主要表单,但initial传递给EventScheduleModelFormSet,这是问题的直接原因。

但是,由于这些模型显然具有外键关系,听起来您应该使用内联模型formset:

from django.forms.models import inlineformset_factory
eventschedule_formset_class = inlineformset_factory(Event, EventSchedule)
event_sched_formset = eventschedule_formset_class(request.POST or None,
                                                  instance=event_to_edit)

现在不需要updateEvent逻辑 - 您只需保存event_sched_formset即可正确引用该事件。

答案 1 :(得分:0)

您是否正在尝试保存EventScheduleModelFormSet表单?没有实例只设置初始数据,因此您每次都要创建一个新对象。或者我错过了什么?

答案 2 :(得分:0)

根据Daniel的建议,在这篇博客文章的帮助下,我能够获得内联模型formset的工作:http://charlesleifer.com/blog/djangos-inlineformsetfactory-and-you/

正如一个FYI,我缺少的一个关键点是formset的实例引用了父模型。此外,如果您在模板中手动显示formset,请不要忘记包含{{formset.id}}。