Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django form not calling clean_<fieldname>

I am attempting to validate a form (and it used to work before). For some reason, I can't seem to get the various cleaning functions such as clean_username(self) to get called when form.is_valid() is called.

I know there are not nearly enough checks yet (they are under construction you see ;-) ), but here are my classes:

  class LoginForm(forms.Form):
    username = forms.CharField(max_length=30)
    password = forms.CharField(max_length=30,widget=forms.PasswordInput)

    def clean_password(self):
        print "Cleaning password"
        password = self.cleaned_data['password']
        if password == u"":
            raise forms.ValidationError("Password is blank.")
        return password

    def clean_username(self):
        username = self.cleaned_data['username']
        if len(username) < 4:
            raise forms.ValidationError("Username is fewer than four charecters.")
        return username


class RegistrationForm( LoginForm ):
        confirm_password = forms.CharField(widget=forms.PasswordInput, max_length=30)
        email = forms.EmailField()

        def clean_confirm_password(self):
            print "Cleaning confirm password"
            clean_confirm_password = self.cleaned_data['confirm_password']
            if clean_confirm_password == u"":
                raise forms.ValidationError("Confirming password is blank.")
            return clean_confirm_password

        def clean(self):
            print "Running clean on a registration form"
            print self.cleaned_data.items()
            password = self.cleaned_data['password']
            confirm = self.cleaned_data['confirm_password']
            if password != confirm:
                raise forms.ValidationError('Passwords do not match.')
            return self.cleaned_data

Thank you!

like image 698
SapphireSun Avatar asked Dec 09 '09 05:12

SapphireSun


2 Answers

I discovered the source of the error after diving into the Django forms.py source.

It seems that if a field is left blank, the form raises a ValidationError for that field after calling field.clean(), but it then does not call clean_<fieldname>, but it still calls the main clean method of the class. In order to deal with a clean method that uses those blank fields you have to do the following:

def clean(self):
    try:
        password = self.cleaned_data['password']
        # etc
    except KeyError:
        raise ValidationError('The password field was blank.')

    return self.cleaned_data
like image 189
SapphireSun Avatar answered Nov 03 '22 18:11

SapphireSun


You can override this by using required=False in your field constructors.

username = forms.CharField(max_length=30, required=False)
password = forms.CharField(max_length=30,widget=forms.PasswordInput, required=False)

This seems illogical for your example, but can be useful if other instances

like image 44
Zach Avatar answered Nov 03 '22 18:11

Zach