user9092892
user9092892

Reputation:

Trying to customize the Django SetPasswordForm

I was trying to overwrite SetPasswordForm to add a placeholder and a class but it seems that it is not working. I managed to do it for login page and password reset page but here I got stuck.

class MySetPasswordForm(SetPasswordForm):
    new_password1 = forms.CharField(
        label=_("New password"),
        widget=forms.PasswordInput(attrs={'placeholder': 'New Password', 'class': 'password1'}),
        strip=False,
        help_text=password_validation.password_validators_help_text_html(),
    )
    new_password2 = forms.CharField(
        label=_("New password confirmation"),
        strip=False,
        widget=forms.PasswordInput(attrs={'placeholder': 'Repeat Password', 'class': 'password2'}),
    )



urlpatterns = [  path('accounts/password_reset/', auth_views.PasswordResetView.as_view(
                      form_class=MyPasswordResetForm)),
                  path('accounts/password_reset_confirm/', auth_views.PasswordResetConfirmView.as_view(
                      form_class=MySetPasswordForm)),
                  path('accounts/', include('django.contrib.auth.urls')),]

Is this accurate ?

Upvotes: 2

Views: 3817

Answers (2)

Vinay Kumar
Vinay Kumar

Reputation: 1307

Override or customize the django auth setPasswordFrom and PasswordResetForm, answer already give but without using path() in django url i.e django 1.11 I have done in below ways. Copy the setPasswordFrom form folder structure django.contrib.auth.forms import SetPasswordForm.

In urls.py

    from django.conf import settings
    from django.conf.urls import url
    from django.conf.urls.static import static
    from django.contrib.auth import views as auth_views
    from GetAdmin360.forms import (EmailValidationOnForgotPassword, CustomSetPasswordForm)

urlpatterns = [
url(r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', auth_views.PasswordResetConfirmView.as_view(form_class = CustomSetPasswordForm), {'template_name': 'registration/password_reset_confirm.html'}, name='password_reset_confirm'),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

In forms.py in which I have override the setPasswordFrom and PasswordResetForm

from django.contrib.auth.forms import (PasswordResetForm, SetPasswordForm)
from MyApp.models import MyUser

class EmailValidationOnForgotPassword(PasswordResetForm):
    def clean_email(self):
        email = self.cleaned_data['email']
        if not MyUser.objects.filter(email__iexact=email, is_active=True).exists():
            raise ValidationError("The email address you entered is not registered. Please enter registered email id")
        return email


class CustomSetPasswordForm(SetPasswordForm):
    """
    A form that lets a user change set their password without entering the old
    password
    """
    error_messages = {
        'password_mismatch': _("The two password fields didn't match."),
        'password_notvalid': _("Password must of 8 Character which contain alphanumeric with atleast 1 special charater and 1 uppercase."),
    }
    new_password1 = forms.CharField(
        label=_("New password"),
        widget=forms.PasswordInput,
        strip=False,
        help_text=password_validation.password_validators_help_text_html(),
    )
    new_password2 = forms.CharField(
        label=_("New password confirmation"),
        strip=False,
        widget=forms.PasswordInput,
    )

    def __init__(self, user, *args, **kwargs):
        self.user = user
        super(SetPasswordForm, self).__init__(*args, **kwargs)

    def clean_new_password2(self):
        password1 = self.cleaned_data.get('new_password1')
        password2 = self.cleaned_data.get('new_password2')
        if password1 and password2:
            if password1 != password2:
                raise forms.ValidationError(
                    self.error_messages['password_mismatch'],
                    code='password_mismatch',
                )
            # Regix to check the password must contains sepcial char, numbers, char with upeercase and lowercase.
            regex = re.compile('((?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%]).{8,30})')
            if(regex.search(password1) == None):
                    raise forms.ValidationError(
                    self.error_messages['password_notvalid'],
                    code='password_mismatch',
                )

        password_validation.validate_password(password2, self.user)
        return password2

    def save(self, commit=True):
        password = self.cleaned_data["new_password1"]
        self.user.set_password(password)
        if commit:
            self.user.save()
        email = self.user.email
        instance = MyUser.objects.get(id=self.user.id)
        if not instance.first_login:
            instance.first_login = True
            instance.save()
        return self.user

Upvotes: 0

Alasdair
Alasdair

Reputation: 308939

You’re using the wrong path in your URL patterns. It should be:

'reset/<uidb64>/<token>/'

Upvotes: 3

Related Questions