使用ModelForm编辑模型实例会创建新实例而不是更新

jak*_*car 4 django django-models django-forms

我正在尝试创建一个允许用户编辑模型实例的视图(在这种情况下是一个事件).不幸的是,提交此表单会创建一个新实例(带有新ID),甚至不会删除旧实例.我的印象是在这种情况下save方法应该更新实例...

注意:EventForm是一个ModelForm

我已尝试使用force_update arg按https://docs.djangoproject.com/en/dev/ref/models/instances/#forcing-an-insert-or-update,但没有骰子.我也试过删除form.is_valid()块中的原始事件(通过调用event.delete())但是......没有骰子.

我觉得这commit=False是问题吗?我不确定!

谢谢.

(请忽略代码段中的间距问题)

def edit_event(request, event_id):
 event = Event.objects.get(pk=event_id)  

 if request.method == 'POST':
     post_data = request.POST.copy()

     # here is some validation that can't be done in the ModelForm...

     #form = EventForm(post_data, request.FILES, instance=event)
     form = EventForm(post_data, request.FILES)

     if form.is_valid():

         edited_event = form.save(commit=False)

         edited_event.save(force_update=True) # doesn't work with or without force_update arg

         #form.save_m2m() # needed for ManyToMany relationship

         return HttpResponseRedirect('/events/view/%s' % edited_event.id)
  else:
      form = EventForm(instance=event)

return render_to_response('create_event.html', {'form': form,}, context_instance=RequestContext(request) )
Run Code Online (Sandbox Code Playgroud)

UPDATE

我摆脱了模型上的M2M关系,所以我能够摆脱这form.save_m2m()条线.那仍然行不通.

我还尝试在提交表单时不传递实例,假设在用户提交时将预先填充正确的字段(现在就是这种情况).这仍然无效.

在更新模型时,我错过了一个重要的细节吗?

Mir*_*oka 5

我认为你应该像这样初始化表单(因为你已经注释掉了).

form = EventForm(post_data, request.FILES, instance=event)
Run Code Online (Sandbox Code Playgroud)

然后事件对象与表单相关联,并且form.save()可以执行更新而不是插入.


pca*_*cao 3

据我所知,您的代码的问题在于您总是在保存之前创建一个新实例。由于您已经在“event = Event.objects.get(pk=event_id)”中获得了事件的实例,因此您可以简单地更改此实例并保存它,我很确定这会导致 django 做出一个更新。

我建议您查看此链接: https://docs.djangoproject.com/en/dev/ref/models/instances/ ?from=olddocs#how-django-knows-to-update-vs-insert

它对 Django 用于区分插入和更新的算法有一个非常简单的解释。如果你的对象没有主键集(可能是 django 在你syncdb时自动创建的“id”字段),那么它将被视为一个新对象。如果它设置了该字段,那么 Django 将尝试在数据库中查找该特定记录,如果存在,它将被更新。

希望答案足够清楚。