Модель Django: как добавить поле подтверждения пароля?

Здесь мне нужно добавить дополнительный confirmation password в моей форме. Я использовал модель формы Джанго. Мне также нужно проверить оба пароля. Это должно вызвать ошибку проверки, если 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} )

5 ответов

Решение

Использование 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"
            )
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

Попробуйте это для 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')

Вы можете посмотреть, как 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

Здесь пароль2 относится к полю confirm_password, при условии, что оно появляется после поля пароля. Попытка использовать ту же реализацию для clean_password может привести к ошибке, что данные confirm_password не найдены.

Это имеет то преимущество, что вы вызываете ошибку для определенного поля, а не для всей формы, которую затем можно соответствующим образом отобразить в своем шаблоне.

Однако, если вы пытаетесь проверить данные по нескольким полям, в документации рекомендуется переопределитьclean() метод, как ответил Савай.

Исходный код доступен здесь.

Подтверждение пароля уже доступно в UserCreationForm

      class UserRegistrationForm(UserCreationForm):
    email = forms.EmailField(required=True)

    class Meta:
        model = User
        fields = ("username", "email", "password1", "password2")

Это автоматически проверитpassword1==password2когда вызывается form.is_valid().

Здесь я беру электронную почту только в качестве аргументов отдельной формы для дальнейшей очистки и проверки.

Другие вопросы по тегам