为什么检查Django中的两个密码是否匹配如此复杂?

mpe*_*pen 14 django design-patterns

我做错了什么,或者这是开发人员希望我每次想要检查两个字段是否相同的时候认真对待的内容?

def clean(self):
    data = self.cleaned_data
    if "password1" in data and "password2" in data:
        if data["password1"] != data["password2"]:
            self._errors["password2"] = self.error_class(['Passwords do not match.'])
            del data['password2']    
    return data
Run Code Online (Sandbox Code Playgroud)

为什么我必须验证用户名是否唯一?

def clean_username(self):
    data = self.cleaned_data['username']
    if User.objects.filter(username=data).exists():
        raise ValidationError('Username already taken.')
    return data
Run Code Online (Sandbox Code Playgroud)

这是一个ModelForm.它应该已经知道有一个独特的约束?

Yuj*_*ita 28

这就是我要做的事情:

这是您需要定义的唯一干净方法,以确保2个密码正确并且用户名有效.

使用该clean_fieldname方法,以便您不需要做更多工作来验证用户名.

def clean_password2(self):
    password1 = self.cleaned_data.get('password1')
    password2 = self.cleaned_data.get('password2')

    if not password2:
        raise forms.ValidationError("You must confirm your password")
    if password1 != password2:
        raise forms.ValidationError("Your passwords do not match")
    return password2
Run Code Online (Sandbox Code Playgroud)

你是绝对正确的,你需要验证的用户名是唯一的,因为的ModelForm知道它必须是唯一的.

您的代码的问题在于您重写了该clean()方法,这意味着ModelForm没有执行其"真正的"clean().

要获得默认验证,请调用super(MyForm, self).clean()或更好,但根本不要覆盖clean并仅指定clean_password2.


Dan*_*man 5

首先,您是否认真抱怨四行样板代码?如果它确实让您烦恼,请创建一个PasswordForm包含干净逻辑的类,并根据需要将其子类化为您自己的表单。

其次,您不必手动验证唯一约束。正如你所说,ModelForm 会为你做这件事。

评论后编辑

这种“奇怪的语法”是因为检查两个密码字段是否匹配是与正常方案不同的流程。首先,您要检查 mainclean方法而不是特定于字段的clean_myfield. 如果是后者,您只需引发一个异常,Django 就会确实删除字段数据。

所以不,这不是每个表单上的 7 行 - 请参阅我关于子类化的注释 - 并且它肯定不是 7 行乘以多个字段,因为您不想对任何其他类型的字段执行此操作。


Ste*_*Nch 5

http://k0001.wordpress.com/2007/11/15/dual-password-field-with-django/


编辑:找出管理表单处理问题的方式:http://code.djangoproject.com/svn/django/trunk/django/contrib/auth/forms.py

class AdminPasswordChangeForm(forms.Form):
    """
    A form used to change the password of a user in the admin interface.
    """
    password1 = forms.CharField(label=_("Password"), widget=forms.PasswordInput)
    password2 = forms.CharField(label=_("Password (again)"), widget=forms.PasswordInput)

    def __init__(self, user, *args, **kwargs):
        self.user = user
        super(AdminPasswordChangeForm, self).__init__(*args, **kwargs)

    def clean_password2(self):
        password1 = self.cleaned_data.get('password1')
        password2 = self.cleaned_data.get('password2')
        if password1 and password2:
            if password1 != password2:
                raise forms.ValidationError(_("The two password fields didn't match."))
        return password2

    def save(self, commit=True):
        """
        Saves the new password.
        """
        self.user.set_password(self.cleaned_data["password1"])
        if commit:
            self.user.save()
        return self.user
Run Code Online (Sandbox Code Playgroud)