Bytes
Bytes

Reputation: 721

Django password validation not working

I am using my own custom User model, but I'm inheriting off of django.contrib.auth User model. I have a username, email, and password field. I don't explicitly add the password field because it gets added by default by the inheritance. When I try to create a superuser through the command line, the normal default Django password validation is working correctly. However, when I have a sign up form, it is not. Email and username validation are working properly when I click submit, but there is no password validation. I can enter whatever I want and it would accept the password.

Here's my forms.py

class RegisterForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ['username', 'email', 'password']

    username    = forms.CharField(label='Username', widget=forms.TextInput(attrs={'placeholder': 'Username:'}))
    email       = forms.EmailField(label='Email', widget=forms.EmailInput(attrs={'placeholder': 'Email:'}))
    password    = forms.CharField(label='Password', widget=forms.PasswordInput(attrs={'placeholder': 'Password:'}))

Here's my view:

class RegisterView(SuccessMessageMixin, View):
    form_class = RegisterForm
    template_name = 'oauth/auth_form.html'
    success_message = "You have successfully created an account!"

    # Display blank form
    def get(self, request):
        form = self.form_class(None)
        return render(request, self.template_name, {'form': form})

    def post(self, request):
        form = self.form_class(request.POST)

        if form.is_valid():
            user = form.save(commit=False) # Do not save to table yet

            username = form.cleaned_data['username']
            password = form.cleaned_data['password']

            user.set_password(password)
            user.save()

            # Let's try to login the user
            user = authenticate(username=username, password=password)

            if user is not None:

                    login(request, user)
                    return redirect('profiles: index')

        return render(request, self.template_name, {'form': form})

How can I make it so that the password field gets validated correctly with the default password validation from Django?

Upvotes: 2

Views: 7024

Answers (1)

user2390182
user2390182

Reputation: 73500

Django has some utils to integrate password validation. The easiest would be to call the validate_password function in the field specific clean_password method of the form, but since you need a user instance for some validators, I shall demonstrate its use in the view:

from django.contrib.auth.password_validation import validate_password
from django.core.exceptions import ValidationError

class RegisterView(SuccessMessageMixin, View):
    # ...
    def post(self, request):

        if form.is_valid():
            user = form.save(commit=False) # Do not save to table yet
            username = form.cleaned_data['username']
            password = form.cleaned_data['password']

            try:
                validate_password(password, user)
            except ValidationError as e:
                form.add_error('password', e)  # to be displayed with the field's errors
                return render(request, self.template_name, {'form': form})
            # ...

        return render(request, self.template_name, {'form': form})

Upvotes: 9

Related Questions