views:

88

answers:

2

Hello everyone,

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!

+2  A: 

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
SapphireSun
+1 for digging into forms.py. It amazes me how people will not look into the available source code.
celopes
It can be scary. I'm afraid of accidently changing and saving something important. Irrational, I know when the whole thing can be replaced easily. ;-)
SapphireSun
+2  A: 

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

Zach