编辑视图保存两次

时间:2017-03-11 12:44:46

标签: python django

def edit(request, id):
    post = get_object_or_404(Post, id=id)
    edit_form = EditPostForm(request.POST or None, instance=post)
    if edit_form.is_valid():
        instance = edit_form.save(commit=False)
        instance.save(update_fields=['content'])

这是我的修改视图,用于更新Post(它只更新content字段)。然而,发生的情况是Post保存两次,因此它在我的查询集中显示两次。我在视图代码中有2个保存是问题,但我还能在这里执行编辑吗?

完整视图:

def edit(request, id):
    post = get_object_or_404(Post, id=id)
    edit_form = EditPostForm(request.POST or None, instance=post)
    if edit_form.is_valid():
        instance = edit_form.save(commit=False)
        instance.save(update_fields=['content'])
        return HttpResponseRedirect('/')
    else:
        print(edit_form.errors)
        edit_form = PostForm(instance=post)
    context = {
        'edit_form': edit_form,
        'form_post': post
    }
    return render(request, 'edit.html', context)

SQL:

[11/Mar/2017 13:11:57] "GET /post/edit/192/ HTTP/1.1" 200 7394
[11/Mar/2017 13:12:08] "POST /post/edit/192/ HTTP/1.1" 302 0
[11/Mar/2017 13:12:08] "GET / HTTP/1.1" 302 0
[11/Mar/2017 13:12:08] "GET /home/ HTTP/1.1" 200 20044

修改

视图

def edit(request, id):
    post = get_object_or_404(Post, id=id)
    print('CAT:', post.category)
    edit_form = EditPostForm(request.POST or None, instance=post)
    if edit_form.is_valid():
        print('Edit valid')
        instance = edit_form.save(commit=False)
        instance.save(update_fields=['content'])
        return HttpResponseRedirect('/')
    else:
        print('Errors:', edit_form.errors)
        print('Non-field Errors:', edit_form.non_field_errors)
        edit_form = PostForm(instance=post)
    context = {
        'edit_form': edit_form,
        'form_post': post
    }
    return render(request, 'edit.html', context)
编辑帖子时

终端输出:

CAT: 1
Errors: 
Non-field Errors: <bound method BaseForm.non_field_errors of <EditPostForm bound=False, valid=False, fields=(content)>>
[23/May/2017 04:37:22] "GET /post/edit/37/ HTTP/1.1" 200 7430
CAT: 1
Edit valid
每次创建帖子时

def create_post_score(sender, **kwargs):
    score = PostScore.objects.create(post=kwargs['instance'])
    print(score.upvotes)

post_save.connect(create_post_score, sender=Post)

2 个答案:

答案 0 :(得分:1)

当您查看save method时,它清楚地显示在commit = False时没有执行sql命令。当您执行instance.save

时,实际的数据库调用将在您的下一行中进行

如果您看到发生了两次更新,可能是因为表单正在提交两次。这可以安全地被忽略,因为许多RDBMS足够聪明,不能更新未更改的数据。但是,即使这样也可以通过在表单处理后使用标准的django重定向模式来避免

instance = edit_form.save(commit=False)
instance.save(update_fields=['content'])
return HttpResponseRediret('/success_url/')

答案 1 :(得分:0)

您需要在视图中指定request.method,否则表单也会在get请求中提交。 因为,表单已包含&#34; post&#34;例如,表单已经有效并且已保存。

像这样编辑您的视图,

def edit(request, id):
    post = get_object_or_404(Post, id=id)
    #If it is a POST request do the thing below.
    if request.method == "POST":
        edit_form = EditPostForm(request.POST or None, instance=post)
        if edit_form.is_valid():
            form.instance.save(update_fields=['content'])
            return HttpResponseRedirect('/')
    else:
        edit_form = EditPostForm(instance=post)
    context = {
            'edit_form': edit_form,
            'form_post': post
            }
    return render(request, 'edit.html', context)