Indentation Error. The validators are inside the META
instead of RegistrationForm
.
Django: ModelForm validation not working
Question
I am trying to create a user registration form. I know there is a built-in user registration form in Django but I am challenging myself to create one.
I created a ModelForm from User model and wrote few methods to validate and confirm password . But it seems that the methods, clean_password()
and clean()
are not being executed by form.is_valid()
at views.py
.
Below is the snippet of RegistrationForm -
class RegistrationForm(ModelForm):
re_password = CharField(widget = PasswordInput(attrs = {'placeholder' : 'Re-password'}))
class Meta:
model = User
fields = ['username', 'email', 'password']
widgets = {
'username' : TextInput(attrs = {'placeholder':'Username'}),
'email' : EmailInput(attrs = {'placeholder' : 'Email'}),
'password' : PasswordInput(attrs = {'placeholder' : 'Password'})
}
def clean_password(self):
password = self.cleaned_data['password']
if len(password) < 6:
raise forms.ValidationError('Password not long enough. Should be >= 6')
return password
def clean(self):
if not self.cleaned_data['password'] == self.cleaned_data['re_password']:
raise forms.ValidationError("Passwords should match")
return self.cleaned_data
Additional question
The password
does not seem to be encrypted by form.save()
. I had to create new User instance and call its .set_password()
method to encrypt it. Is this the right way to do it?
Solution 2
OTHER TIPS
You are correct about having to set the password. Your view should look something like:
if form.is_valid():
user = form.save(commit=False) # Don't waste the database write
user.set_password(form.cleaned_data['password'])
user.save()
Update
you need to remove your
clean_password
method and addvalidators=[validators.MinLengthValidator(6)]
to thepassword
model field's declaration (or simply definepassword
as a field on the form manually, and providemin_length=6
to it).You need to dedent your
clean
method by 1 level or it will never be called (it's currently being defined as a method on yourMeta
class).
Firstly, you can define min_length of password field in __init__
method of form, like this:
def __init__(self, *args, **kwargs):
super(RegistrationForm, self).__init__(*args, **kwargs)
self.fields['password'].min_length = 6
In second, yes, this right way