2

I used custom form for register users. I want do validation for 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

template:

<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)

How can I add validation for password(also confirm password)?

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
Rustam Pulatov
  • 625
  • 1
  • 9
  • 20

3 Answers3

4

You inherit from UserCreationForm [GitHub]. This form already does that for you.

Indeed: the clean_password2 will validate that the two passwords are the same:

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

The _post_clean function will validate that the password is a valid password:

    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:
                password_validation.validate_password(password, self.instance)
            except forms.ValidationError as error:
                self.add_error('password2', error)

Finally in the save() it will use .set_password() to set the password. This is necessary, since Django's User model will, like any good user model, hash the password.

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

You thus should not interfere with these. You here only want to add first_name and last_name. So you can add that logic with:

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', 'email', 'first_name', 'last_name']

That's all, since the ModelForm will take care of that.

Note that authenticate in your view is probably not necessary, since if you construct a user, it should authenticate. You can just login here:

def registration_view(request):
    context = {}
    context.update(csrf(request))
    if request.method == 'POST':
        form = RegistrationForm(request.POST)
        if form.is_valid():
            newuser = form.save()
            auth.login(request, newuser)
        return redirect('home')
    else:
        form = RegistrationForm()
    context['form'] = form
    return render(request, '/registration.html', context)
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
1

Try to use this in your register template

<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>
Muzaffar
  • 51
  • 1
  • 7
0

I find mistake

<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>
Rustam Pulatov
  • 625
  • 1
  • 9
  • 20