Reputation: 637
I need to overwrite the clean()
method in a Django Model form to perform additional uniqueness checks on the data entered.
This page gives implementation details: https://docs.djangoproject.com/en/1.11/ref/forms/validation/ Copied here:
def clean(self):
cleaned_data = super(ContactForm, self).clean()
cc_myself = cleaned_data.get("cc_myself")
subject = cleaned_data.get("subject")
if cc_myself and subject:
# Only do something if both fields are valid so far.
if "help" not in subject:
raise forms.ValidationError(
"Did not send for 'help' in the subject despite "
"CC'ing yourself."
)
However I'm confused why this method doesn't return cleaned_data
at the end of the function? Surely that is the correct thing to do?
Upvotes: 9
Views: 5196
Reputation: 956
In Django < 1.7, form.clean()
was required to return a dictionary of cleaned_data
.
This method may still return a dictionary of data to be used, but it’s no longer required.
Upvotes: 0
Reputation: 2921
Have a look at django's _clean_form
method:
def _clean_form(self):
try:
cleaned_data = self.clean()
except ValidationError as e:
self.add_error(None, e)
else:
if cleaned_data is not None:
self.cleaned_data = cleaned_data
Read the last bullet point on the forms doc and especially this bit of the ModelForm doc.
If the clean
method raises a ValidationError
, the error gets added to the forms' errors.
If the clean
method has returned anything and threw no errors, the form is going to use that for its cleaned_data
attribute. Otherwise it will keep its 'old' one.
In your case, all that your clean
method does, is validating an aspect of the form.
Upvotes: 8
Reputation: 9977
The example you are interested in is an override of the clean
method for related fields. This means that it validates a logic that implicate more than one field. Consider this as the form's clean
method. Thus, you don't want to return any values in this case.
As the doc says :
"Be careful when doing this in practice, since it can lead to confusing form output. We’re showing what is possible here and leaving it up to you and your designers to work out what works effectively in your particular situation."
It depends on your particular case, but in my experience with overriding clean
on one particular field, you'll want to return it if the validation passes. Again, this is for only one field.
Here's another example from the doc, but for one field validation:
def clean_recipients(self):
data = self.cleaned_data['recipients']
if "[email protected]" not in data:
raise forms.ValidationError("You have forgotten about Fred!")
# Always return a value to use as the new cleaned data, even if
# this method didn't change it.
return data
Upvotes: 0