24

这里我需要在我的表单中添加一个额外confirmation password的内容。我使用了 Django 的模型表单。我还需要验证两个密码。如果 .它必须引发验证错误password1 != password2

这是我的forms.py:

class UserForm(forms.ModelForm):
    password=forms.CharField(widget=forms.PasswordInput())

    class Meta:
        model=User
        fields=('username','email','password')

class UserProfileForm(forms.ModelForm):
    YESNO_CHOICES = (('male', 'male'), ('female', 'female'))
    sex = forms.TypedChoiceField(choices=YESNO_CHOICES, widget=forms.RadioSelect)
    FAVORITE_COLORS_CHOICES=(('red','red'),('blue','blue'))
    favorite_colors = forms.MultipleChoiceField(required=False,widget=forms.CheckboxSelectMultiple, choices=FAVORITE_COLORS_CHOICES)
    dob = forms.DateField(widget=forms.DateInput(format = '%d/%m/%Y'), 
                                 input_formats=('%d/%m/%Y',))

    class Meta:

        model=UserProfile
        fields=('phone','picture','sex','favorite_colors','dob')

这是我的注册功能:

def register(request):
    registered = False
    if request.method == 'POST':
        user_form = UserForm(data=request.POST)
        profile_form = UserProfileForm(data=request.POST)



        if user_form.is_valid() and profile_form.is_valid():
            user = user_form.save(commit=False)
            user.set_password(user.password)
            user.save()
            profile = profile_form.save(commit=False)
            profile.user = user
            if 'picture' in request.FILES:
                profile.picture = request.FILES['picture']
            profile.save()
            registered = True
        else:
            print user_form.errors, profile_form.errors
    else:
        user_form = UserForm()
        profile_form = UserProfileForm()

    return render(request,
            'mysite/register.html',
            {'user_form': user_form, 'profile_form': profile_form, 'registered': registered} )
4

4 回答 4

33

使用clean喜欢

class UserForm(forms.ModelForm):
    password=forms.CharField(widget=forms.PasswordInput())
    confirm_password=forms.CharField(widget=forms.PasswordInput())
    class Meta:
        model=User
        fields=('username','email','password')

    def clean(self):
        cleaned_data = super(UserForm, self).clean()
        password = cleaned_data.get("password")
        confirm_password = cleaned_data.get("confirm_password")

        if password != confirm_password:
            raise forms.ValidationError(
                "password and confirm_password does not match"
            )
于 2016-01-17T11:38:41.763 回答
13
def clean(self):
    cleaned_data = super(UserAccountForm, self).clean()
    password = cleaned_data.get("password")
    confirm_password = cleaned_data.get("confirm_password")

    if password != confirm_password:
        self.add_error('confirm_password', "Password does not match")

    return cleaned_data
于 2017-09-15T23:15:58.543 回答
2

试试这个forms.py:

class UserForm(forms.Form):
    password = forms.CharField(widget=forms.PasswordInput())
    password_confirm = forms.CharField(widget=forms.PasswordInput())

    class Meta:
        model = User
        fields=('username','email','password')

这在views.py中:

if user_form.is_valid() and profile_form.is_valid() and user_form.cleaned_data['password'] == user_form.cleaned_data['password_confirm']:
    ...
elif user_form.data['password'] != user_form.data['password_confirm']:
    user_form.add_error('password_confirm', 'The passwords do not match')
于 2016-01-16T18:51:08.317 回答
0

你可以看看 Django 是如何为 UserCreationForm 做的。

    def clean_password2(self):
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
            raise ValidationError(
                self.error_messages['password_mismatch'],
                code='password_mismatch',
            )
        return password2

这里的password2 指的是confirm_password 字段,假设它出现在password 字段之后。尝试对 clean_password 使用相同的实现可能会导致没有找到 confirm_password 数据的错误。

这样做的好处是您要为特定字段而不是整个表单引发错误,然后您可以在模板中适当地呈现它。

但是,如果您尝试跨多个字段验证数据,文档建议覆盖该clean()方法,正如 Savai 所回答的那样。

源代码可在此处获得。

于 2020-07-11T03:58:58.753 回答