Custom form validation methods help you check user input in your forms beyond basic rules. They make sure data is correct and meaningful before saving or using it.
Custom form validation methods in Django
Start learning this pattern below
Jump into concepts and practice - no test required
or
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Introduction
Syntax
Django
class MyForm(forms.Form): field_name = forms.CharField() def clean_field_name(self): data = self.cleaned_data['field_name'] # custom validation logic if some_condition: raise forms.ValidationError('Error message') return data def clean(self): cleaned_data = super().clean() # cross-field validation if condition: raise forms.ValidationError('Error message') return cleaned_data
clean_field_name validates one field at a time.
clean method validates multiple fields together.
Examples
Django
class SignupForm(forms.Form): username = forms.CharField() def clean_username(self): username = self.cleaned_data['username'] if username == 'admin': raise forms.ValidationError('Username cannot be admin') return username
Django
class PasswordForm(forms.Form): password = forms.CharField(widget=forms.PasswordInput) confirm_password = forms.CharField(widget=forms.PasswordInput) def clean(self): cleaned_data = super().clean() pw = cleaned_data.get('password') cpw = cleaned_data.get('confirm_password') if pw and cpw and pw != cpw: raise forms.ValidationError('Passwords do not match') return cleaned_data
Sample Program
This form checks that the email ends with '@example.com' and the message is at least 10 characters long.
Django
from django import forms class ContactForm(forms.Form): email = forms.EmailField() message = forms.CharField(widget=forms.Textarea) def clean_email(self): email = self.cleaned_data['email'] if not email.endswith('@example.com'): raise forms.ValidationError('Email must be from example.com domain') return email def clean(self): cleaned_data = super().clean() message = cleaned_data.get('message') if message and len(message) < 10: raise forms.ValidationError('Message must be at least 10 characters long') return cleaned_data
Important Notes
Always return the cleaned data at the end of your validation methods.
Use raise forms.ValidationError to show errors to users.
Field-specific clean methods run before the general clean() method.
Summary
Custom validation methods let you check form data your way.
Use clean_fieldname for single fields and clean for multiple fields.
Raise ValidationError to show helpful error messages.
Practice
1. What is the purpose of defining a
clean_fieldname method in a Django form?easy
Solution
Step 1: Understand the role of
This method is used to add validation logic for a single field in a Django form.clean_fieldnameStep 2: Differentiate from other methods
Unlikecleanwhich validates multiple fields,clean_fieldnamefocuses on one field only.Final Answer:
To add custom validation logic for a specific form field -> Option CQuick Check:
clean_fieldnamevalidates one field [OK]
Hint: Remember: clean_fieldname validates one field only [OK]
Common Mistakes:
- Confusing clean_fieldname with clean method
- Thinking it saves data automatically
- Assuming it styles the form
2. Which of the following is the correct way to raise a validation error inside a custom clean method for a field named
email?easy
Solution
Step 1: Identify how to raise errors in Django forms
In custom clean methods, you raise aValidationErrorto signal invalid data.Step 2: Check the syntax for raising errors
The correct syntax is to useraise ValidationError('message'), not return or just call it.Final Answer:
raise ValidationError('Invalid email') -> Option BQuick Check:
Use raise to throw ValidationError [OK]
Hint: Use raise, not return, to signal validation errors [OK]
Common Mistakes:
- Using return instead of raise
- Calling ValidationError without raise
- Misusing self.add_error inside clean_fieldname
3. Given this Django form snippet, what will happen if the user enters 'abc' for the
age field?class MyForm(forms.Form):
age = forms.IntegerField()
def clean_age(self):
age = self.cleaned_data.get('age')
if age < 18:
raise ValidationError('Must be at least 18')
return agemedium
Solution
Step 1: Understand IntegerField behavior
IntegerField automatically validates input to be an integer before calling clean_age.Step 2: Analyze input 'abc'
'abc' is not an integer, so IntegerField will raise a validation error before clean_age runs.Final Answer:
Form will raise a validation error because 'abc' is not an integer -> Option DQuick Check:
IntegerField rejects non-integers first [OK]
Hint: IntegerField validates type before custom clean runs [OK]
Common Mistakes:
- Thinking clean_age handles type errors
- Assuming 'Must be at least 18' error triggers for 'abc'
- Expecting a crash instead of validation error
4. Identify the error in this custom form validation method:
def clean(self):
data = self.cleaned_data
if data['start_date'] > data['end_date']:
raise ValidationError('Start date must be before end date')
return datamedium
Solution
Step 1: Check how clean() should be overridden
When overriding clean(), you must callsuper().clean()to get cleaned_data properly.Step 2: Identify the error in accessing cleaned_data
This code accessesself.cleaned_datadirectly without callingsuper().clean(), which may cause missing or incomplete data.Final Answer:
Accessing cleaned_data directly without calling super().clean() -> Option AQuick Check:
Always call super().clean() first [OK]
Hint: Call super().clean() before using cleaned_data [OK]
Common Mistakes:
- Forgetting to call super().clean()
- Returning wrong data type
- Misusing ValidationError format
5. You want to ensure that a Django form's
password and confirm_password fields match. Which is the best way to implement this validation?hard
Solution
Step 1: Understand field-level vs form-level validation
Field-level methods likeclean_passwordonly see one field's data, so can't compare two fields.Step 2: Use form-level clean() for cross-field validation
Overridingcleanlets you access all fields and comparepasswordandconfirm_password.Final Answer:
Override the form's clean method to compare both fields and raise ValidationError if they differ -> Option AQuick Check:
Use clean() for multi-field validation [OK]
Hint: Use clean() method for comparing multiple fields [OK]
Common Mistakes:
- Trying to compare fields in clean_password
- Relying only on client-side JavaScript
- Adding validators that can't access other fields
