Django - ModelForm在数据无效时仍然保存

1 投票
1 回答
524 浏览
提问于 2025-04-16 10:34

大概是这样。

我定义了一个表单,代码是这样的:

class EditUserForm(UserForm):
    def __init__(self,data=None,instance=None):
        UserForm.__init__(self,data=data,instance=instance)
        del self.fields['username']

我这样做是因为我想在编辑用户表单中不显示用户名字段,但由于我在用户表单中重写了用户名字段,django里有个bug导致这个方法不奏效,所以我就这样写了表单。

我的视图代码看起来是这样的:

if request.method == 'POST':
        uf = EditUserForm(request.POST,instance=user)
        upf = StudentProfileForm(request.POST,instance=profile)
        if uf.is_valid() and upf.is_valid(): 
            print 'VALID'
            uf.save()
            upf.save()
            messages.success(request, 'You have successfully updated your profile.')
            return HttpResponseRedirect('/student/editprofile')
        else:
            print 'INVALID'

为了测试,我尝试修改名字并让密码不匹配,提交后我注意到页面上显示了INVALID(密码验证错误正确出现了),但是在页面顶部显示“欢迎(用户的名字)(用户的姓氏)”时,我发现名字已经变了。当我去到其他页面时,它又回到正确的值了。我该怎么做才能不让这种情况发生呢?

这是我的html代码:

{% if user.is_authenticated %}
    Welcome, <a href = "/{{user.get_profile.getType}}/profile">{{user.first_name}} {{user.last_name}}</a> | 
    <a href = "/auth/logout">Logout</a>
{% else %}
{% endif %}

我猜发生的事情是,当我提交数据时,它把user.first_name放进了上下文中,覆盖了实际的user.first_name。但这并不有效,因为数据还没有保存...

那么,我该如何在一个被提交的模板中使用user.first_name,而不在数据有效之前改变它的值呢?

1 个回答

0

你的想法是对的。在验证的时候,ModelForm 会用给定的数据更新指定的实例(这里是 user),但这样可能会让它处于无效状态。

你可以:

  • 尝试创建一个 user 的副本,
  • 从数据库重新加载 user
  • 或者把 user.first_name 存到一个临时变量里,如果验证失败再把它设置回去。

补充一下:虽然 ModelForm 修改了这个实例,但它并不会自动保存这些修改。

撰写回答