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?
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})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With