I have a Django form with a username and email field. I want to check the email isn't already in use by a user:
def clean_email(self):
email = self.cleaned_data["email"]
if User.objects.filter(email=email).count() != 0:
raise forms.ValidationError(_("Email not available."))
return email
This works, but raises some false negatives because the email might already be in the database for the user named in the form. I want to change to this:
def clean_email(self):
email = self.cleaned_data["email"]
username = self.cleaned_data["username"]
if User.objects.filter(email=email, username__ne=username).count() != 0:
raise forms.ValidationError(_("Email not available."))
return email
The Django docs say that all the validation for one field is done before moving onto the next field. If email is cleaned before username, then cleaned_data["username"]
won't be available in clean_email
. But the docs are unclear as to what order the fields are cleaned in. I declare username before email in the form, does that mean I'm safe in assuming that username is cleaned before email?
I could read the code, but I'm more interested in what the Django API is promising, and knowing that I'm safe even in future versions of Django.
Django provides built-in methods to validate form data automatically. Django forms submit only if it contains CSRF tokens. It uses uses a clean and easy approach to validate data. The is_valid() method is used to perform validation for each field of the form, it is defined in Django Form class.
cleaned_data returns a dictionary of validated form input fields and their values, where string primary keys are returned as objects. form. data returns a dictionary of un-validated form input fields and their values in string format (i.e. not objects).
clean_fields() method documentation: This method will validate all fields on your model. The optional exclude argument lets you provide a list of field names to exclude from validation. It will raise a ValidationError if any fields fail validation.
To display the form errors, you use form. is_valid() to make sure that it passes validation. Django says the following for custom validations: Note that any errors raised by your Form.
There's no promise that the fields are processed in any particular order. The official recommendation is that any validation that depends on more than one field should be done in the form's clean()
method, rather than the field-specific clean_foo()
methods.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With