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!
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
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
精彩评论