自定义注册表单。确认密码

Custom registration form. Confirm password

我使用自定义表单注册用户。我想验证确认密码。 forms.py:

class RegistrationForm(UserCreationForm):
    '''Register for new users'''
    email = forms.EmailField(required=True)
    first_name = forms.CharField(required=True)
    last_name = forms.CharField(required=True)

    class Meta:
        model = get_user_model()
        fields = {'username', 'password1', 'password2', 'email', 'first_name', 'last_name'}

    def save(self, commit=True):
        user = super(RegistrationForm, self).save(commit=False)
        user.email = self.cleaned_data['email']
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']

        if commit:
            user.save()

        return user

模板:

<div class="input-group register">
     {{ form.password.errors }}
     <label for="id_password1">Password: </label>
     {{ form.password1 }}
</div>
<div class="input-group register">
    {{ form.password.errors }}
    <label for="id_password2">Confirm password: </label>
    {{ form.password2 }}                            
</div>

views.py

def registration_view(request):
context = {}
context.update(csrf(request))
context['form'] = RegistrationForm()

if request.method == 'POST':
    form = RegistrationForm(request.POST)
    if form.is_valid():
        form.save()
        newuser = auth.authenticate(
            username=form.cleaned_data['username'],
            password=form.cleaned_data['password2']
        )
        auth.login(request, newuser)
        return redirect('home')
    else:
        context['form'] = form

return render(request, '/registration.html', context)

如何添加密码验证(同时确认密码)?

我发现错误

<div class="input-group register">
    {{ form.password1.errors }}
     <label for="id_password1">Пароль: </label>
     {{ form.password1 }}
 </div>
 <div class="input-group register">
     {{ form.password2.errors }}
     <label for="id_password2">Подтвердите пароль: </label>
     {{ form.password2 }}                            
 </div>

您继承自 UserCreationForm [GitHub]。此表格已经为您完成了。

确实:clean_password2 将验证两个密码是否相同:

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

_post_clean 函数将验证密码是否有效:

    def _post_clean(self):
        super()._post_clean()
        # Validate the password after self.instance is updated with form data
        # by super().
        password = self.cleaned_data.get('password2')
        if password:
            try:
                <b>password_validation.validate_password(password, self.instance)</b>
            except forms.ValidationError as error:
                self.add_error('password2', error)

最后在save()中会使用.set_password()设置密码。这是必要的,因为 Django 的 User 模型将像任何好的用户模型一样,散列 密码。

    def save(self, commit=True):
        user = super().save(commit=False)
        user.<b>set_password(self.cleaned_data["password1"])</b>
        if commit:
            user.save()
        return user

因此你不应该干涉这些。您在这里只想添加 first_namelast_name。所以你可以添加这个逻辑:

class RegistrationForm(UserCreationForm):
    '''Register for new users'''
    <b>email</b> = forms.EmailField(required=True)
    <b>first_name</b> = forms.CharField(required=True)
    <b>last_name</b> = forms.CharField(required=True)

    class Meta:
        model = get_user_model()
        fields = <b>['username', 'email', 'first_name', 'last_name']</b>

就是这样,因为 ModelForm 会处理这些。

请注意,您认为 authenticate 可能不是必需的,因为如果您构建用户,它应该进行身份验证。你可以在这里 login:

def registration_view(request):
    context = {}
    context.update(csrf(request))
    if request.method == 'POST':
        form = RegistrationForm(request.POST)
        if form.is_valid():
            <b>newuser</b> = form.save()
            auth.login(request, newuser)
        return redirect('home')
    else:
        form = RegistrationForm()
    context['form'] = form
    return render(request, '/registration.html', context)

尝试在您的注册模板中使用它

<form method="post" id="register-account-form">
                {% csrf_token %}

                {% for field in form %}

                        {% if field.help_text %}
                            <div class="notification error closeable">
                            <small style="color: grey">{{ field.help_text }}</small>
                            <a class="close" href="#"></a>
                            </div>
                        {% endif %}
                        {% for error in field.errors %}
                            <div class="notification error closeable">
                            <p style="color: red">{{ error }}</p>
                            <a class="close" href="#"></a>
                            </div>

                        {% endfor %}
                {% endfor %}


                <div class="input-with-icon-left">
                    <i class="icon-feather-user"></i>
                    {{ form.username }}
                </div>