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):
name = models.CharField(
max_length=100,
validators=[
RegexValidator(r'^[A-Za-z ]+$', message="Only alphabets and spaces allowed")
]
)
age = models.IntegerField(validators=[MinValueValidator(18), MaxValueValidator(65)])
email = models.EmailField(validators=[EmailValidator()])
phone = models.CharField(
max_length=10,
validators=[RegexValidator(r'^\d{10}$', message="Enter a valid 10-digit phone number")]
)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):
name = forms.CharField(
max_length=50,
validators=[RegexValidator(r'^[A-Za-z ]+$', message="Only alphabets allowed")]
)
message = forms.CharField(
widget=forms.Textarea,
validators=[MinLengthValidator(10, message="Message must be at least 10 characters long")]
)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):
name = serializers.CharField(max_length=100)
price = serializers.DecimalField(
max_digits=10,
decimal_places=2,
validators=[MinValueValidator(0)]
)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):
number = models.IntegerField(validators=[validate_even])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):
word_count = len(value.split())
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):
title = models.CharField(max_length=200)
content = models.TextField(validators=[MinWordsValidator(5)])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):
date = models.DateField()
attendees = models.PositiveIntegerField()
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":
form = BookingForm(request.POST)
if form.is_valid():
try:
form.clean() # Manually invoke the validation
form.save()
return render(request, "success.html")
except ValidationError as e:
form.add_error(None, e)
else:
form = BookingForm()
return render(request, "booking_form.html", {"form": form})9. Skipping Validation
You can skip validation when saving a model using:
instance.save(validate=False)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.