2
votes

Formulaire d'inscription personnalisé. Confirmez le mot de passe

J'ai utilisé un formulaire personnalisé pour les utilisateurs du registre. Je veux faire la validation pour confirmer le mot de passe. forms.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)

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

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

Comment puis-je ajouter la validation du mot de passe (également confirmer le mot de passe)?


3 commentaires

Il s'agit d'un formulaire UserCreation , ce qui signifie qu'il est déjà implémenté.


Oui, j'ai essayé ce formulaire comme {{form}}, mais je ne suis pas satisfait de la vue. Sur mon modèle ne fonctionne pas, comparez deux mots de passe.


Merci, Willem Van Onsem.


3 Réponses :


0
votes

Je trouve l'erreur

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


0 commentaires

3
votes

Vous héritez de UserCreationForm [GitHub] . Ce formulaire le fait déjà pour vous.

En effet: le clean_password2 validera que les deux mots de passe sont identiques:

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

La fonction _post_clean validera que le mot de passe est un mot de passe valide:

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']

Enfin dans le save () il utilisera .set_password () pour définir le mot de passe. Ceci est nécessaire, car le modèle User de Django, comme tout bon modèle d'utilisateur, hachera le mot de passe.

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

Vous ne devez donc pas interférer avec ceux-ci. Ici, vous ne voulez ajouter que first_name et last_name . Vous pouvez donc ajouter cette logique avec:

    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)

C'est tout, puisque le ModelForm s'en chargera.

Remarque que authentifier dans votre vue n'est probablement pas nécessaire, car si vous construisez un utilisateur, il devrait s'authentifier. Vous pouvez simplement vous connecter ici:

    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


3 commentaires

Je vous remercie. J'ai vu cette décision. Et je vais utiliser la validation personnalisée pour le mot de passe


@RustamPulatov: alors je vous suggère de remplacer le _post_clean avec votre propre validation :). Mais vous n'avez probablement pas à réécrire le reste du formulaire :)


Je comprends. Merci beaucoup.



1
votes

Essayez de l'utiliser dans votre modèle de registre

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


0 commentaires