Reputation: 721
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
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