2011-05-28 50 views
4

我正在试图制作一个允许用户编辑模型实例(本例中为事件)的视图。不幸的是,提交这个表单会创建一个新的实例(带有一个新的ID),甚至不会删除旧的实例。我的印象是,保存方法,被认为在这种情况下,以更新实例下...使用ModelForm编辑模型实例会创建新的实例而不是更新

注:EventForm是的ModelForm

我使用每https://docs.djangoproject.com/en/dev/ref/models/instances/#forcing-an-insert-or-update的force_update ARG尝试过,但没有骰子。我也尝试删除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)) 

UPDATE

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

我也试过在提交表单时没有通过实例,假设当用户提交时(现在是这种情况)正确的字段将被预先填充。这仍然不起作用。

我错过了一个重要的细节,当涉及到更新模型?

回答

2

从我所能理解的,你的代码的问题是,你总是在保存之前创建一个新的实例。由于您已经在“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使用的插入和更新来区分一个相当简单的解释。如果你的对象没有它的主键集(可能是你在syncdb时django自动创建的“id”字段),那么它将被视为一个新的对象。如果它设置了该字段,那么Django将尝试在数据库中查找该特定记录,如果它存在,它将被更新。

希望答案很清楚。

-3

你的例子太复杂了。尝试从简单的模型/视图/表单开始。用一个简单的字段创建新模型,然后创建模型表单和视图并确保它们可以工作。然后开始修改视图以使其更接近实际状态。

+0

?你的推理是什么,我的例子太复杂了?在我看到的Django文档中没有任何地方说过... – jakecar 2011-05-28 16:09:42

5

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

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

然后事件对象与以下形式相关联,并且可以form.save()代替执行插入的更新。

0

资料中显示和更新工作代码:

@login_required(login_url=LOGIN_URL) 
@csrf_exempt 
def profile(request): 
    """ 
    :param request: 
    :param: 
    :return: 
    """ 
    val = get_object_or_404(Profil, user=request.user) 

if request.method == 'POST': 
    form = ProfilForm(request.POST, request.FILES, instance=val) 
    if form.is_valid(): 
     form.save() 
     msg_ok = u'Profil updated' 
    else: 
     msg_err = u"Invalid form." 
else: 
    form = ProfilForm(instance=val) 

return render(request, "back/profile.html", locals()) 
相关问题