Django Form Validations

Form validation in Django ensures that the data submitted by users is clean, meets the expected format, and adheres to any specific rules or constraints defined for the fields. This process helps maintain the integrity of your application’s data and improves user experience by providing meaningful error messages when invalid data is entered.

Types of Validations

1. Predefined Validations

These validations come predefined with Django and are automatically applied based on the field type.

Example:


from django import forms

class ContactForm(forms.Form):
    name = forms.CharField(
        max_length=100, 
        required=True,  # Ensures the field is not empty
        label="Name"
    )
    email = forms.EmailField(
        required=True, 
        label="Email"
    )
    age = forms.IntegerField(
        min_value=18,  # Ensures the value is at least 18
        max_value=100, # Ensures the value is at most 100
        required=True, 
        label="Your Age"
    )
    message = forms.CharField(
        widget=forms.Textarea, 
        required=False,  # Optional field
        label="Your Message"
    )

2. Custom Field-Level Validations

You can define custom logic for validating individual fields by creating a clean_<fieldname> method. This method is called during the validation process for that specific field.


class ContactForm(forms.Form):
    name = forms.CharField(max_length=100, label="Name")
    email = forms.EmailField(label="Your Email")
    age = forms.IntegerField(min_value=18, label="Age")
    message = forms.CharField(widget=forms.Textarea, required=False, label="Your Message")

    def clean_email(self):
        email = self.cleaned_data.get('email')
        if not email.endswith('@example.com'):
            raise forms.ValidationError("Email must be from the domain '@example.com'.")
        return email

Note:- clean_email: This method checks if the email ends with @example.com. If not, it raises a ValidationError.

3. Custom Form-Level Validations

You can override the clean() method to validate the relationships between multiple fields or apply complex validation logic.


class ContactForm(forms.Form):
    name = forms.CharField(max_length=100, label="Name")
    email = forms.EmailField(label="Email")
    confirm_email = forms.EmailField(label="Confirm Email")
    age = forms.IntegerField(min_value=18, label="Your Age")
    message = forms.CharField(widget=forms.Textarea, required=False, label="Your Message")

    def clean(self):
        cleaned_data = super().clean()
        email = cleaned_data.get('email')
        confirm_email = cleaned_data.get('confirm_email')

        if email != confirm_email:
            raise forms.ValidationError("Emails do not match!")
        
        return cleaned_data

Customize Error Messages

To customize error messages for fields, use the error_messages parameter.

Example:


class ContactForm(forms.Form):
    name = forms.CharField(
        max_length=100, 
        label="Your Name",
        error_messages={
            'required': 'Name is required!',
            'max_length': 'Name cannot exceed 100 characters.',
        }
    )
    email = forms.EmailField(
        label="Your Email",
        error_messages={
            'required': 'Email is required!',
            'invalid': 'Enter a valid email address.',
        }
    )

Rendering Errors in Templates

In your template, you can display form errors like this:


<form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    {% for field in form %}
        {% if field.errors %}
            <ul>
                {% for error in field.errors %}
                    <li style="color: red;">{{ error }}</li>
                {% endfor %}
            </ul>
        {% endif %}
    {% endfor %}
    <button type="submit">Submit</button>
</form>