Form validation is the process of checking whether data submitted by a user is correct, complete, and follows the required rules.
Django provides a powerful validation system for checking form fields, cleaning submitted data, and displaying useful error messages to users.
Form validation checks whether the submitted data satisfies the rules defined by the application.
For example:
Validation helps applications handle incorrect or incomplete user input.
A typical validation process looks like this:
User submits form
↓
Django receives data
↓
Form validation
↓
Valid?
↙ ↘
Yes No
↓ ↓
cleaned_data Errors
Only after successful validation should the application use the validated data for the intended operation.
The is_valid() method starts the form validation process.
if form.is_valid():
print("Form is valid")
It returns True when validation succeeds and
False when validation errors are found.
Many Django form fields are required by default.
name = forms.CharField()
If the user submits an empty value, Django can generate a validation error.
You can explicitly specify this behavior:
name = forms.CharField(
required=True
)
Use required=False when a field should be optional.
phone = forms.CharField(
required=False
)
The user can submit the form without providing a value for this field.
Django's EmailField performs email-format validation.
email = forms.EmailField()
For example, a value such as:
student@example.com
has a valid email-style format, while an incomplete email value can cause a validation error.
Use IntegerField when the form should accept an integer.
age = forms.IntegerField()
Django validates that the submitted value can be interpreted as an integer.
Numeric fields can use minimum and maximum validators.
from django.core.validators import (
MinValueValidator,
MaxValueValidator
)
age = forms.IntegerField(
validators=[
MinValueValidator(18),
MaxValueValidator(60)
]
)
This example accepts values from 18 through 60.
Text fields can use min_length and max_length.
username = forms.CharField(
min_length=3,
max_length=20
)
The submitted value must satisfy the specified length limits.
When validation fails, Django stores error information in the form.
if not form.is_valid():
print(form.errors)
Errors can also be displayed automatically through normal form rendering.
{{ form.as_p }}
Django provides ValidationError for creating custom validation
errors.
from django.core.exceptions import (
ValidationError
)
You can raise this exception when submitted data does not meet a custom rule.
A clean_<fieldname>() method can validate one specific field.
class StudentForm(forms.Form):
name = forms.CharField(
max_length=100
)
def clean_name(self):
name = self.cleaned_data[
"name"
]
return name
The method is called during form validation.
You can add your own rule to a field.
def clean_name(self):
name = self.cleaned_data[
"name"
]
if len(name) < 3:
raise forms.ValidationError(
"Name must contain at least 3 characters."
)
return name
The value is returned after successful validation.
A field-level cleaning method can also normalize data before it is used.
def clean_name(self):
name = self.cleaned_data[
"name"
]
return name.strip().title()
This can remove unnecessary spaces and standardize the value.
After successful validation, Django stores cleaned values in
cleaned_data.
if form.is_valid():
name = form.cleaned_data[
"name"
]
email = form.cleaned_data[
"email"
]
Use cleaned_data rather than relying directly on raw submitted
values after validation.
The clean() method is useful when validation depends on more
than one field.
def clean(self):
cleaned_data = super().clean()
return cleaned_data
This method can examine multiple fields together.
For example, password and confirmation password can be compared using form-level validation.
class RegisterForm(forms.Form):
password = forms.CharField(
widget=forms.PasswordInput
)
confirm_password = forms.CharField(
widget=forms.PasswordInput
)
def clean(self):
cleaned_data = super().clean()
password = cleaned_data.get(
"password"
)
confirm = cleaned_data.get(
"confirm_password"
)
if password and confirm:
if password != confirm:
raise forms.ValidationError(
"Passwords do not match."
)
return cleaned_data
Django provides reusable validators that can be attached to fields.
from django.core.validators import (
MinValueValidator
)
age = forms.IntegerField(
validators=[
MinValueValidator(18)
]
)
Validators are useful when the same type of rule needs to be reused.
RegexValidator can be used when input must match a specific
pattern.
from django.core.validators import (
RegexValidator
)
mobile = forms.CharField(
validators=[
RegexValidator(
r'^[0-9]{10}$',
'Enter a valid 10-digit mobile number.'
)
]
)
This example expects exactly ten digits.
ModelForms also support custom validation.
class StudentForm(forms.ModelForm):
class Meta:
model = Student
fields = [
"name",
"email"
]
def clean_name(self):
name = self.cleaned_data[
"name"
]
if len(name) < 3:
raise forms.ValidationError(
"Name is too short."
)
return name
Django provides several ways to display form errors.
A simple approach is:
{{ form.as_p }}
You can also display errors for an individual field:
{{ form.name.errors }}
This gives you more control over the form's HTML layout.
Errors that apply to the entire form rather than one particular field are called non-field errors.
{{ form.non_field_errors }}
These are commonly produced by form-level validation.
A typical view validates submitted form data before processing it.
from django.shortcuts import render
from .forms import StudentForm
def student_create(request):
if request.method == "POST":
form = StudentForm(
request.POST
)
if form.is_valid():
data = form.cleaned_data
print(data)
else:
form = StudentForm()
return render(
request,
"student_form.html",
{"form": form}
)
For a ModelForm, save the object only after validation succeeds.
if form.is_valid():
form.save()
return redirect(
"student_list"
)
If validation fails, the form is returned with its errors.
Some duplicate checks can be handled through model constraints and ModelForm validation.
For example, a model field can be configured as unique:
email = models.EmailField(
unique=True
)
Django can then validate uniqueness when processing a ModelForm for this field.
is_valid().cleaned_data when validation succeeds.forms.py
from django import forms
class StudentForm(forms.Form):
name = forms.CharField(
max_length=100
)
email = forms.EmailField()
age = forms.IntegerField(
min_value=18,
max_value=60
)
def clean_name(self):
name = self.cleaned_data[
"name"
]
if len(name) < 3:
raise forms.ValidationError(
"Name must contain at least 3 characters."
)
return name
views.py
from django.shortcuts import render
from .forms import StudentForm
def student_form(request):
if request.method == "POST":
form = StudentForm(
request.POST
)
if form.is_valid():
name = form.cleaned_data[
"name"
]
email = form.cleaned_data[
"email"
]
age = form.cleaned_data[
"age"
]
print(
name,
email,
age
)
else:
form = StudentForm()
return render(
request,
"student_form.html",
{"form": form}
)
student_form.html
<form method="post">
{% csrf_token %}
{{ form.non_field_errors }}
{{ form.as_p }}
<button type="submit">
Submit
</button>
</form>
form.is_valid().cleaned_data before successful validation.is_valid().Django provides a complete validation system for checking and cleaning form data before it is processed.
is_valid() starts the validation process.clean_<fieldname>() validates individual fields.clean() validates multiple fields together.cleaned_data contains validated values.ValidationError creates custom validation errors.form.is_valid() determines whether validation succeeds.cleaned_data contains cleaned and validated values.clean_<fieldname>() for individual field validation.clean() for validation involving multiple fields.ValidationError can be used for custom validation messages.Question: Which method is used to check whether a Django form is valid?