Skip to main content
Validators can be useful for reusing validation logic between different types of fields. REST framework includes several validator classes that enforce various constraints.

UniqueValidator

Enforces the unique=True constraint on model fields.

Class Signature

UniqueValidator(
    queryset,
    message=None,
    lookup='exact'
)
queryset
QuerySet
required
Queryset against which uniqueness is enforced.
message
str
Custom error message. Defaults to 'This field must be unique.'
lookup
str
default:"'exact'"
Lookup type for finding existing instances.

Usage

Apply to serializer fields:
from rest_framework.validators import UniqueValidator

class BlogPostSerializer(serializers.Serializer):
    slug = serializers.SlugField(
        max_length=100,
        validators=[UniqueValidator(queryset=BlogPost.objects.all())]
    )

Example

class UserSerializer(serializers.ModelSerializer):
    email = serializers.EmailField(
        validators=[UniqueValidator(queryset=User.objects.all())]
    )

    class Meta:
        model = User
        fields = ['username', 'email']

UniqueTogetherValidator

Enforces unique_together constraints on model instances.

Class Signature

UniqueTogetherValidator(
    queryset,
    fields,
    message=None,
    condition_fields=None,
    condition=None,
    code=None
)
queryset
QuerySet
required
Queryset against which uniqueness is enforced.
fields
list | tuple
required
List of field names that must form a unique set.
message
str
Custom error message. Defaults to 'The fields {field_names} must make a unique set.'
condition_fields
list
Additional fields required by the condition.
condition
Q
Django Q object for conditional uniqueness.
code
str
default:"'unique'"
Error code for validation failures.

Usage

Apply to serializer classes:
from rest_framework.validators import UniqueTogetherValidator

class ToDoItemSerializer(serializers.Serializer):
    list = serializers.PrimaryKeyRelatedField(queryset=ToDoList.objects.all())
    position = serializers.IntegerField()
    title = serializers.CharField(max_length=100)

    class Meta:
        validators = [
            UniqueTogetherValidator(
                queryset=ToDoItem.objects.all(),
                fields=['list', 'position']
            )
        ]

Example

class EventSerializer(serializers.ModelSerializer):
    class Meta:
        model = Event
        fields = ['room_number', 'date', 'name']
        validators = [
            UniqueTogetherValidator(
                queryset=Event.objects.all(),
                fields=['room_number', 'date'],
                message='Each room can only have one event per day.'
            )
        ]
Note: All fields in UniqueTogetherValidator are implicitly required unless they have a default value.

UniqueForDateValidator

Enforces unique_for_date constraint.

Class Signature

UniqueForDateValidator(
    queryset,
    field,
    date_field,
    message=None
)
queryset
QuerySet
required
Queryset against which uniqueness is enforced.
field
str
required
Field name to validate for uniqueness.
date_field
str
required
Field name to use for date range.
message
str
Custom error message. Defaults to 'This field must be unique for the "{date_field}" date.'

Usage

from rest_framework.validators import UniqueForDateValidator

class BlogPostSerializer(serializers.ModelSerializer):
    class Meta:
        model = BlogPost
        fields = ['slug', 'published', 'title']
        validators = [
            UniqueForDateValidator(
                queryset=BlogPost.objects.all(),
                field='slug',
                date_field='published'
            )
        ]

Date Field Styles

Writable date field:
published = serializers.DateTimeField(required=True)
Read-only date field:
published = serializers.DateTimeField(read_only=True, default=timezone.now)
Hidden date field:
published = serializers.HiddenField(default=timezone.now)

UniqueForMonthValidator

Enforces unique_for_month constraint.

Class Signature

UniqueForMonthValidator(
    queryset,
    field,
    date_field,
    message=None
)
queryset
QuerySet
required
Queryset against which uniqueness is enforced.
field
str
required
Field name to validate for uniqueness.
date_field
str
required
Field name to use for month range.
message
str
Custom error message. Defaults to 'This field must be unique for the "{date_field}" month.'

Example

class ArticleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Article
        fields = ['slug', 'published', 'title']
        validators = [
            UniqueForMonthValidator(
                queryset=Article.objects.all(),
                field='slug',
                date_field='published'
            )
        ]

UniqueForYearValidator

Enforces unique_for_year constraint.

Class Signature

UniqueForYearValidator(
    queryset,
    field,
    date_field,
    message=None
)
queryset
QuerySet
required
Queryset against which uniqueness is enforced.
field
str
required
Field name to validate for uniqueness.
date_field
str
required
Field name to use for year range.
message
str
Custom error message. Defaults to 'This field must be unique for the "{date_field}" year.'

Example

class BlogPostSerializer(serializers.ModelSerializer):
    class Meta:
        model = BlogPost
        fields = ['slug', 'published', 'title']
        validators = [
            UniqueForYearValidator(
                queryset=BlogPost.objects.all(),
                field='slug',
                date_field='published'
            )
        ]

Default Classes

CurrentUserDefault

Default class that returns the current user.
CurrentUserDefault()
Requires request in serializer context. Example:
owner = serializers.HiddenField(
    default=serializers.CurrentUserDefault()
)

CreateOnlyDefault

Default class that sets a value only during create operations.
CreateOnlyDefault(default)
default
any
required
Default value or callable for create operations.
Example:
created_at = serializers.DateTimeField(
    default=serializers.CreateOnlyDefault(timezone.now)
)

Custom Validators

Function-Based Validator

def even_number(value):
    if value % 2 != 0:
        raise serializers.ValidationError('This field must be an even number.')

class GameRecordSerializer(serializers.Serializer):
    score = serializers.IntegerField(validators=[even_number])

Class-Based Validator

class MultipleOf:
    def __init__(self, base):
        self.base = base

    def __call__(self, value):
        if value % self.base != 0:
            message = 'This field must be a multiple of %d.' % self.base
            raise serializers.ValidationError(message)

class GameRecordSerializer(serializers.Serializer):
    score = serializers.IntegerField(validators=[MultipleOf(10)])

Context-Aware Validator

class MultipleOf:
    requires_context = True

    def __init__(self, base):
        self.base = base

    def __call__(self, value, serializer_field):
        if value % self.base != 0:
            message = 'This field must be a multiple of %d.' % self.base
            raise serializers.ValidationError(message)

Disabling Validators

Disable automatically generated validators:
class BillingRecordSerializer(serializers.ModelSerializer):
    def validate(self, attrs):
        # Custom validation logic here
        return attrs

    class Meta:
        model = BillingRecord
        fields = ['client', 'date', 'amount']
        extra_kwargs = {'client': {'required': False}}
        validators = []  # Disable automatic validators

Limitations

Optional Fields

For optional fields in unique_together constraints:
class Meta:
    validators = []  # Disable automatic validator

def validate(self, attrs):
    # Implement custom validation logic
    if 'field1' in attrs and 'field2' in attrs:
        # Check uniqueness
        pass
    return attrs

Nested Serializers

For nested serializers, uniqueness validators may need to be disabled:
class ParentSerializer(serializers.ModelSerializer):
    children = ChildSerializer(many=True)

    class Meta:
        model = Parent
        fields = ['name', 'children']
        # ChildSerializer should have validators=[] if needed

Build docs developers (and LLMs) love