为什么django表单即使在验证失败时也在更新用户对象

时间:2016-01-28 23:46:51

标签: django forms validation

我有一个基于名为CustomUser的自定义用户模型的django ModelForm。我的CustomUser中的电子邮件字段设置为唯一,以便电子邮件不会在不同帐户下重复使用。

当我尝试添加重复的电子邮件时,在我的表单中,django ModelForm无法通过验证,这很棒。但是,它似乎更新了该视图中用户对象的电子邮件。当我尝试引用request.user.email时,我会收到验证失败的电子邮件,而不是用户的电子邮件。

为了解决这个问题,我在验证失败时从db刷新对象,但为什么需要?如果验证失败,为什么ModelForm会改变我的对象?

class CustomUser(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(verbose_name="email_address", unique=True,
        error_messages={
            'unique': "This email address is already registered.",
        })


class MemberSettingsForm(forms.ModelForm):
    """
    Member Form
    """
    class Meta:
        model = CustomUser
        fields = ['username', 'email', 'first_name', 'last_name', 'profile_pic']


class MemberSettings(View):
    """
    Member settings view
    """
    @method_decorator(login_required)
    def get(self, request):
        form = MemberSettingsForm(instance=request.user)
        return render(request, 'member/settings_profile.html', {'form': form})    

    @method_decorator(login_required)
    def post(self, request):
        form = MemberSettingsForm(request.POST, request.FILES, instance=request.user)
        if form.is_valid():
            form.save()
            return redirect('member')
        request.user.refresh_from_db()
        return render(request, 'member/settings_profile.html', {'form': form})

我正在使用django 1.8

1 个答案:

答案 0 :(得分:2)

ModelForm验证分为两部分。在表单调用自己的字段和表单级验证方法之后,它需要调用任何模型验证方法,包括唯一性验证。要做到这一点,它需要一个最新的模型实例,所以它将首先执行此操作。

通常情况并不重要,因为您正在更新的内容是专门为此目的查询的,而不是在视图中的其他位置使用。在您的情况下,从数据库中明确刷新它听起来像一个很好的解决方案。