Lesson 43 of 60 – Django Form Validation
72%

Django Form Validation

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.

Note: Always validate user input before using it in your application logic or saving it to the database.

1. What is Form Validation?

Form validation checks whether the submitted data satisfies the rules defined by the application.

For example:

  • Name should not be empty.
  • Email should have a valid format.
  • Age should be a valid number.
  • Password fields may need to match.
  • A mobile number may need a specific format.

2. Why is Validation Important?

Validation helps applications handle incorrect or incomplete user input.

  • Prevent invalid data.
  • Improve data quality.
  • Provide useful feedback to users.
  • Enforce application rules.
  • Reduce unexpected errors.

3. Django Validation Process

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.

4. Using is_valid()

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.

5. Required Field Validation

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
)

6. Optional Fields

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.

7. Email Validation

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.

8. Integer Validation

Use IntegerField when the form should accept an integer.

age = forms.IntegerField()

Django validates that the submitted value can be interpreted as an integer.

9. Minimum and Maximum Values

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.

10. MinLength and MaxLength

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.

11. Validation Errors

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 }}

12. ValidationError

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.

13. Field-Level Validation

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.

14. Custom Name 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.

15. Converting or Cleaning Data

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.

16. cleaned_data

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.

17. Form-Level 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.

18. Comparing Two Fields

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

19. Using Validators

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.

20. Regex Validation

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.

21. Validation in ModelForm

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

22. Displaying Errors in Template

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.

23. Non-Field Errors

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.

24. Validation in a View

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}
    )

25. Validation and Saving Data

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.

26. Preventing Duplicate Data

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.

27. Complete Validation Workflow

  1. Create the form.
  2. Display the form to the user.
  3. User submits data.
  4. Create a bound form using submitted data.
  5. Call is_valid().
  6. Django runs field validation.
  7. Django runs custom field validation.
  8. Django runs form-level validation.
  9. Use cleaned_data when validation succeeds.
  10. Save or process the validated data.

28. Complete Form Validation Example

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>

29. Common Validation Mistakes

  • Forgetting to call form.is_valid().
  • Using cleaned_data before successful validation.
  • Forgetting to return the cleaned value from a field cleaning method.
  • Using incorrect field names.
  • Not displaying validation errors to users.
  • Putting single-field validation in the wrong place.
  • Using form-level validation when field-level validation is sufficient.
  • Saving ModelForm data before checking is_valid().
  • Forgetting CSRF protection for internal POST forms.

30. Form Validation Summary

Django provides a complete validation system for checking and cleaning form data before it is processed.

  • is_valid() starts the validation process.
  • Required fields prevent empty values when appropriate.
  • Built-in fields provide common validation.
  • Validators can enforce reusable rules.
  • clean_<fieldname>() validates individual fields.
  • clean() validates multiple fields together.
  • cleaned_data contains validated values.
  • ValidationError creates custom validation errors.
  • ModelForms also support custom validation.
  • Validated data should be processed only after successful validation.

📌 Key Points

  • Form validation checks whether submitted data follows required rules.
  • form.is_valid() determines whether validation succeeds.
  • cleaned_data contains cleaned and validated values.
  • Use clean_<fieldname>() for individual field validation.
  • Use clean() for validation involving multiple fields.
  • ValidationError can be used for custom validation messages.
  • Django provides built-in validators such as minimum and maximum value validators.
  • Validation errors can be displayed in Django templates.
  • ModelForms also support custom validation.
  • Always validate submitted data before saving or processing it.

🧠 Quick Quiz

Question: Which method is used to check whether a Django form is valid?