我做错了什么,或者严重每次我想检查两个字段是否相同时,开发人员希望我写的是什么?
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
为什么我必须验证用户名是否唯一?
def clean_username(self):
data = self.cleaned_data['username']
if User.objects.filter(username=data).exists():
raise ValidationError('Username already taken.')
return data
这是一个ModelForm
。它应该已经知道有一个独特的约束条件吗?
答案 0 :(得分: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
您绝对正确,不需要验证用户名是唯一的,因为ModelForm知道它必须是唯一的。
您的代码存在的问题是您要覆盖clean()
方法,这意味着ModelForm不会执行其真正的'干净()。
要获得默认验证,请致电super(MyForm, self).clean()
或更好,但根本不要覆盖clean
并仅指定clean_password2
。
答案 1 :(得分:4)
首先,您是否严重抱怨四行样板代码?如果它真的困扰你,请创建一个包含该干净逻辑的PasswordForm
类,并根据需要将其子类化为您自己的表单。
其次,您不必须手动验证唯一约束。如你所说,ModelForm为你做到了。
在评论后修改
这种“奇怪的语法”是因为检查两个密码字段匹配的是不同的流而不是正常的方案。首先,您要检查主clean
方法,而不是特定于字段的clean_myfield
。如果它是后者,你只是引发异常,Django确实删除了字段数据。
所以不,这不是每个表单上的7行 - 请参阅我关于子类化的说明 - 并且当然不是7行乘以多个字段,因为你不想这样做对于任何其他类型的领域。
答案 2 :(得分:4)
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
答案 3 :(得分:1)
您可能希望为第一个else:
添加if
部分。目前该函数返回data
而不设置任何错误,即使其中一个密码不存在 - 是否是预期的行为?
else:
self._errors["password"] = self.error_class(['One or both of the passwords not found'])
if "password1" in data and "password2" in data:
这可以确保两个密码都存在。如果没有这一行,如果其中任何一个不存在,您将在下一行中看到data[password1]
和data[password2]
的错误。
接下来的三行比较密码并设置相应的错误信息 - 这是必需的,不是吗?
正如他们所说,让事情尽可能简单,不再是。