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?

Was it helpful?

Solution 2

Indentation Error. The validators are inside the META instead of RegistrationForm.

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

  1. you need to remove your clean_password method and add validators=[validators.MinLengthValidator(6)] to the password model field's declaration (or simply define password as a field on the form manually, and provide min_length=6 to it).

  2. 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 your Meta 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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top