Validator
1. Where to Use Validators
Validators can be applied in: 1. Django Models (models.py
) - Ensures data integrity at the database level. 2. Django Forms (forms.py
) - Validates user input before saving. 3. Django REST Framework (DRF) Serializers (serializers.py
) - Validates API input.
2. Built-in Validators
Django provides several built-in validators in django.core.validators
.
2.1 Common Built-in Validators
Validator | Description | Example |
---|---|---|
MinValueValidator(x) |
Ensures the value is at least x |
models.IntegerField(validators=[MinValueValidator(1)]) |
MaxValueValidator(x) |
Ensures the value is at most x |
models.IntegerField(validators=[MaxValueValidator(100)]) |
MinLengthValidator(x) |
Ensures the string length is at least x |
models.CharField(validators=[MinLengthValidator(5)]) |
MaxLengthValidator(x) |
Ensures the string length is at most x |
models.CharField(validators=[MaxLengthValidator(50)]) |
RegexValidator(regex, message, code) |
Ensures the value matches a regular expression | models.CharField(validators=[RegexValidator(r'^\d{4}$', message="Enter 4 digits")]) |
EmailValidator |
Ensures the value is a valid email format | models.EmailField(validators=[EmailValidator()]) |
URLValidator |
Ensures the value is a valid URL | models.URLField(validators=[URLValidator()]) |
validate_slug |
Ensures the value is a valid slug (alphanumeric + hyphens/underscores) | models.SlugField(validators=[validate_slug]) |
validate_ipv4_address |
Ensures the value is a valid IPv4 address | models.GenericIPAddressField(validators=[validate_ipv4_address]) |
validate_ipv6_address |
Ensures the value is a valid IPv6 address | models.GenericIPAddressField(validators=[validate_ipv6_address]) |
validate_comma_separated_integer_list |
Ensures the value contains only comma-separated integers | models.CharField(validators=[validate_comma_separated_integer_list]) |
3. Using Validators in Models
You can add validators to model fields to ensure data is stored correctly.
Example: Using Multiple Validators in a Model
from django.db import models
from django.core.validators import MinValueValidator, MaxValueValidator, RegexValidator, EmailValidator
class Employee(models.Model):
= models.CharField(
name =100,
max_length=[
validatorsr'^[A-Za-z ]+$', message="Only alphabets and spaces allowed")
RegexValidator(
]
)= models.IntegerField(validators=[MinValueValidator(18), MaxValueValidator(65)])
age = models.EmailField(validators=[EmailValidator()])
email = models.CharField(
phone =10,
max_length=[RegexValidator(r'^\d{10}$', message="Enter a valid 10-digit phone number")]
validators )
4. Using Validators in Forms
In forms, you can specify validators inside forms.py
.
Example: Validating an Input Field
from django import forms
from django.core.validators import MinLengthValidator, MaxLengthValidator, RegexValidator
class ContactForm(forms.Form):
= forms.CharField(
name =50,
max_length=[RegexValidator(r'^[A-Za-z ]+$', message="Only alphabets allowed")]
validators
)= forms.CharField(
message =forms.Textarea,
widget=[MinLengthValidator(10, message="Message must be at least 10 characters long")]
validators )
5. Using Validators in Django REST Framework (DRF) Serializers
When using Django REST Framework (DRF), validators ensure API inputs are valid.
Example: Using Validators in a Serializer
from rest_framework import serializers
from django.core.validators import MinValueValidator, MaxValueValidator
class ProductSerializer(serializers.Serializer):
= serializers.CharField(max_length=100)
name = serializers.DecimalField(
price =10,
max_digits=2,
decimal_places=[MinValueValidator(0)]
validators )
6. Creating Custom Validators
If built-in validators don’t meet your requirements, you can create custom validators.
6.1 Function-Based Custom Validator
A function-based validator raises a ValidationError
if input is invalid.
from django.core.exceptions import ValidationError
def validate_even(value):
"""Ensure the value is an even number."""
if value % 2 != 0:
raise ValidationError(f'{value} is not an even number.')
# Using it in a model
class MyModel(models.Model):
= models.IntegerField(validators=[validate_even]) number
6.2 Class-Based Custom Validator
A class-based validator allows reusability and multiple validation rules.
from django.core.exceptions import ValidationError
class MinWordsValidator:
"""Ensure the input has at least `min_words` words."""
def __init__(self, min_words=3):
self.min_words = min_words
def __call__(self, value):
= len(value.split())
word_count if word_count < self.min_words:
raise ValidationError(f'Must have at least {self.min_words} words.')
# Using it in a model
class BlogPost(models.Model):
= models.CharField(max_length=200)
title = models.TextField(validators=[MinWordsValidator(5)]) content
7. Raising Validation Errors Manually
Django allows you to raise validation errors in model’s clean()
method.
Example: Enforcing a Business Rule in a Model
from django.core.exceptions import ValidationError
from django.db import models
class Booking(models.Model):
= models.DateField()
date = models.PositiveIntegerField()
attendees
def clean(self):
if self.attendees > 100:
raise ValidationError({'attendees': 'Maximum 100 attendees allowed.'})
8. Validating in Django Views
If using function-based or class-based views, you can manually validate input.
Example: Manually Validating User Input in a View
from django.core.exceptions import ValidationError
from django.shortcuts import render
from .models import Booking
from .forms import BookingForm
def booking_view(request):
if request.method == "POST":
= BookingForm(request.POST)
form if form.is_valid():
try:
# Manually invoke the validation
form.clean()
form.save()return render(request, "success.html")
except ValidationError as e:
None, e)
form.add_error(else:
= BookingForm()
form return render(request, "booking_form.html", {"form": form})
9. Skipping Validation
You can skip validation when saving a model using:
=False) instance.save(validate
Use with caution! It bypasses all validation rules, which may lead to database inconsistencies.
10. Debugging Validators
If a validation error occurs, check: - If the validator function is executed using print statements or logging. - Raise exceptions to test: python raise ValidationError("Custom error message")
- Use Django’s shell to test manually: bash python manage.py shell >>> from myapp.models import Booking >>> b = Booking(date="2025-01-01", attendees=150) >>> b.full_clean() # Manually run all model validation ValidationError: {'attendees': ['Maximum 100 attendees allowed.']}
11. Summary Table
Validator Type | Example Use Case | Notes |
---|---|---|
Built-in Validators | MinValueValidator(10) |
Simple and efficient |
Function-Based Validators | validate_even(value) |
Best for simple conditions |
Class-Based Validators | MinWordsValidator(min_words=5) |
Best for reusable rules |
Form Validation | forms.CharField(validators=[RegexValidator()]) |
Ensures user input is valid before saving |
Serializer Validation | serializers.CharField(validators=[MinLengthValidator(5)]) |
Ensures API input is correct |
Model Clean Method | def clean(self): ... |
Allows complex, multi-field validation |
Final Thoughts
- Use built-in validators where possible.
- Use function-based or class-based validators for reusable custom rules.
- Leverage
clean()
in models for multi-field validation. - Debug issues using Django Shell (
python manage.py shell
).
Django validators are a powerful way to enforce data integrity and business rules at different levels.