CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-djangorestframework

Web APIs for Django, made easy.

Pending
Overview
Eval results
Files

fields-validation.mddocs/

Fields and Validation

Comprehensive field types for data validation and serialization in Django REST Framework. Includes basic types, specialized fields, relationship fields, and custom validation support.

Capabilities

Base Field Class

Foundation class for all serializer fields providing core validation and transformation functionality.

class Field:
    """
    Base class for all serializer fields.
    """
    def __init__(self, read_only=False, write_only=False, required=None, default=empty, 
                 initial=empty, source=None, label=None, help_text=None, 
                 style=None, error_messages=None, validators=None, allow_null=False):
        """
        Initialize field with configuration options.
        
        Args:
            read_only (bool): Field is read-only
            write_only (bool): Field is write-only  
            required (bool): Field is required for input
            default: Default value if not provided
            initial: Initial value for forms
            source (str): Source attribute name
            label (str): Human readable label
            help_text (str): Help text for field
            style (dict): Style hints for rendering
            error_messages (dict): Custom error messages
            validators (list): List of validator functions
            allow_null (bool): Allow None values
        """
    
    def bind(self, field_name, parent):
        """
        Bind field to its parent serializer.
        
        Args:
            field_name (str): Field name in serializer
            parent: Parent serializer instance
        """
    
    def get_value(self, dictionary):
        """
        Extract field value from input dictionary.
        
        Args:
            dictionary (dict): Input data dictionary
            
        Returns:
            Field value or empty sentinel
        """
    
    def get_attribute(self, instance):
        """
        Extract field value from object instance.
        
        Args:
            instance: Object instance to serialize
            
        Returns:
            Attribute value
        """
    
    def to_representation(self, value):
        """
        Transform internal value to serialized representation.
        
        Args:
            value: Internal Python value
            
        Returns:
            Serialized representation
        """
    
    def to_internal_value(self, data):
        """
        Transform input data to internal Python value.
        
        Args:
            data: Input data to validate
            
        Returns:
            Validated internal value
            
        Raises:
            ValidationError: If validation fails
        """
    
    def validate(self, value):
        """
        Validate internal value against field validators.
        
        Args:
            value: Value to validate
            
        Returns:
            Validated value
            
        Raises:
            ValidationError: If validation fails
        """

Basic Field Types

Core field types for common data validation needs.

class BooleanField(Field):
    """Boolean field accepting True/False values."""
    def __init__(self, **kwargs): ...

class CharField(Field):
    """
    String field with length validation.
    
    Args:
        max_length (int): Maximum string length
        min_length (int): Minimum string length
        allow_blank (bool): Allow empty strings
        trim_whitespace (bool): Strip leading/trailing whitespace
    """
    def __init__(self, max_length=None, min_length=None, allow_blank=False, 
                 trim_whitespace=True, **kwargs): ...

class EmailField(CharField):
    """Email address validation field."""
    def __init__(self, **kwargs): ...

class RegexField(CharField):
    """
    String field validated against regex pattern.
    
    Args:
        regex (str or Pattern): Regular expression pattern
    """
    def __init__(self, regex, **kwargs): ...

class SlugField(CharField):
    """Slug validation field (letters, numbers, underscores, hyphens)."""
    def __init__(self, **kwargs): ...

class URLField(CharField):
    """URL validation field."""
    def __init__(self, **kwargs): ...

class UUIDField(Field):
    """
    UUID field supporting string and UUID object formats.
    
    Args:
        format (str): Output format ('hex_verbose', 'hex', 'int', 'urn')
    """
    def __init__(self, format='hex_verbose', **kwargs): ...

class IPAddressField(CharField):
    """
    IP address validation field supporting IPv4 and IPv6.
    
    Args:
        protocol (str): 'both', 'ipv4', or 'ipv6'
        unpack_ipv4 (bool): Unpack IPv4-mapped IPv6 addresses
    """
    def __init__(self, protocol='both', unpack_ipv4=False, **kwargs): ...

Numeric Fields

Fields for numeric data with range validation.

class IntegerField(Field):
    """
    Integer field with range validation.
    
    Args:
        max_value (int): Maximum allowed value
        min_value (int): Minimum allowed value  
    """
    def __init__(self, max_value=None, min_value=None, **kwargs): ...

class FloatField(Field):
    """
    Float field with range validation.
    
    Args:
        max_value (float): Maximum allowed value
        min_value (float): Minimum allowed value
    """
    def __init__(self, max_value=None, min_value=None, **kwargs): ...

class DecimalField(Field):
    """
    Precise decimal field for financial calculations.
    
    Args:
        max_digits (int): Maximum number of digits
        decimal_places (int): Number of decimal places
        coerce_to_string (bool): Return as string instead of Decimal
        max_value (Decimal): Maximum allowed value
        min_value (Decimal): Minimum allowed value
    """
    def __init__(self, max_digits, decimal_places, coerce_to_string=None,
                 max_value=None, min_value=None, **kwargs): ...

Date and Time Fields

Fields for temporal data with format support.

class DateTimeField(Field):
    """
    DateTime field with format parsing and output.
    
    Args:
        format (str): Output format string or 'iso-8601'
        input_formats (list): List of acceptable input formats
        default_timezone (timezone): Default timezone for naive datetimes
    """
    def __init__(self, format=empty, input_formats=None, default_timezone=None, **kwargs): ...

class DateField(Field):
    """
    Date field with format parsing and output.
    
    Args:
        format (str): Output format string or 'iso-8601'  
        input_formats (list): List of acceptable input formats
    """
    def __init__(self, format=empty, input_formats=None, **kwargs): ...

class TimeField(Field):
    """
    Time field with format parsing and output.
    
    Args:
        format (str): Output format string or 'iso-8601'
        input_formats (list): List of acceptable input formats
    """
    def __init__(self, format=empty, input_formats=None, **kwargs): ...

class DurationField(Field):
    """
    Duration field supporting various input formats.
    
    Args:
        max_value (timedelta): Maximum duration
        min_value (timedelta): Minimum duration
    """
    def __init__(self, max_value=None, min_value=None, **kwargs): ...

Choice and File Fields

Fields for constrained choices and file handling.

class ChoiceField(Field):
    """
    Field that validates against a set of choices.
    
    Args:
        choices (list): List of valid choices as (value, label) tuples
        allow_blank (bool): Allow empty string choice
    """
    def __init__(self, choices, allow_blank=False, **kwargs): ...

class MultipleChoiceField(ChoiceField):
    """
    Field that validates multiple selections from choices.
    
    Args:
        choices (list): List of valid choices
        allow_empty (bool): Allow empty list
    """
    def __init__(self, allow_empty=True, **kwargs): ...

class FileField(Field):
    """
    File upload field.
    
    Args:
        max_length (int): Maximum filename length
        allow_empty_file (bool): Allow empty files
        use_url (bool): Use URL instead of filename in representation
    """
    def __init__(self, max_length=None, allow_empty_file=False, use_url=True, **kwargs): ...

class ImageField(FileField):
    """
    Image file field with validation.
    """
    def __init__(self, **kwargs): ...

Container Fields

Fields for complex data structures.

class ListField(Field):
    """
    Field for lists of items with child validation.
    
    Args:
        child (Field): Field for validating list items
        allow_empty (bool): Allow empty lists
        max_length (int): Maximum list length
        min_length (int): Minimum list length
    """
    def __init__(self, child=None, allow_empty=True, max_length=None, min_length=None, **kwargs): ...

class DictField(Field):
    """
    Field for dictionaries with optional child validation.
    
    Args:
        child (Field): Field for validating dictionary values
        allow_empty (bool): Allow empty dictionaries
    """
    def __init__(self, child=None, allow_empty=True, **kwargs): ...

class HStoreField(DictField):
    """PostgreSQL HStore field (string keys and values only)."""
    def __init__(self, **kwargs): ...

class JSONField(Field):
    """
    Field for JSON data with optional binary encoding.
    
    Args:
        binary (bool): Store as binary JSON (PostgreSQL)
        encoder (JSONEncoder): Custom JSON encoder class
    """
    def __init__(self, binary=False, encoder=None, **kwargs): ...

Special Fields

Specialized fields for specific use cases.

class ReadOnlyField(Field):
    """
    Read-only field that returns attribute value without validation.
    """
    def __init__(self, **kwargs):
        kwargs['read_only'] = True
        super().__init__(**kwargs)

class HiddenField(Field):
    """
    Hidden field with default value, not included in input validation.
    """
    def __init__(self, **kwargs):
        kwargs['write_only'] = True
        super().__init__(**kwargs)

class SerializerMethodField(Field):
    """
    Field that gets its value by calling a method on the serializer.
    
    Args:
        method_name (str): Name of serializer method to call
    """
    def __init__(self, method_name=None, **kwargs):
        kwargs['read_only'] = True
        self.method_name = method_name
        super().__init__(**kwargs)

class ModelField(Field):
    """
    Field that wraps a Django model field for validation.
    
    Args:
        model_field: Django model field instance
    """
    def __init__(self, model_field, **kwargs): ...

Validation Utilities

Support for custom validation logic.

# Special values and exceptions
empty = object()  # Sentinel for no data provided

class SkipField(Exception):
    """Exception to skip field during serialization."""

# Default value classes
class CreateOnlyDefault:
    """Default value only used during object creation."""
    def __init__(self, default): ...
    def __call__(self): ...

class CurrentUserDefault:
    """Default to current user from request context."""
    def __call__(self): ...

# Utility functions
def is_simple_callable(obj):
    """
    Check if object is a simple callable (no required arguments).
    
    Args:
        obj: Object to check
        
    Returns:
        bool: True if simple callable
    """

def get_attribute(instance, attrs):
    """
    Get nested attribute value using dot notation.
    
    Args:
        instance: Object instance
        attrs (list): List of attribute names
        
    Returns:
        Attribute value
    """

def to_choices_dict(choices):
    """
    Convert choices list to dictionary format.
    
    Args:
        choices: Choices in various formats
        
    Returns:
        dict: Normalized choices dictionary
    """

Validator Classes

Built-in validator classes for complex validation scenarios, particularly useful for model-level constraints and uniqueness checks.

class UniqueValidator:
    """
    Validator that ensures field value is unique within a queryset.
    Corresponds to unique=True on model fields.
    """
    message = 'This field must be unique.'
    requires_context = True
    
    def __init__(self, queryset, message=None, lookup='exact'):
        """
        Args:
            queryset: QuerySet to check uniqueness against
            message (str): Custom error message
            lookup (str): Field lookup type for filtering
        """
    
    def __call__(self, value, serializer_field):
        """Validate value uniqueness."""

class UniqueTogetherValidator:
    """
    Validator that ensures field combinations are unique.
    Corresponds to unique_together model Meta option.
    """
    message = 'The fields {field_names} must make a unique set.'
    missing_message = 'This field is required.'
    requires_context = True
    
    def __init__(self, queryset, fields, message=None):
        """
        Args:
            queryset: QuerySet to check uniqueness against
            fields (list): List of field names that must be unique together
            message (str): Custom error message
        """

class UniqueForDateValidator:
    """
    Validator that ensures field is unique for a given date.
    Corresponds to unique_for_date model field option.
    """
    message = 'This field must be unique for the "{date_field}" date.'
    requires_context = True
    
    def __init__(self, queryset, field, date_field, message=None):
        """
        Args:
            queryset: QuerySet to check uniqueness against
            field (str): Field name to validate
            date_field (str): Date field to check uniqueness within
            message (str): Custom error message
        """

class UniqueForMonthValidator:
    """
    Validator that ensures field is unique for a given month.
    Corresponds to unique_for_month model field option.
    """
    message = 'This field must be unique for the "{date_field}" month.'

class UniqueForYearValidator:
    """
    Validator that ensures field is unique for a given year.
    Corresponds to unique_for_year model field option.
    """
    message = 'This field must be unique for the "{date_field}" year.'

class ProhibitSurrogateCharactersValidator:
    """
    Validator that prohibits surrogate characters in text fields.
    """
    message = 'Surrogate characters are not allowed.'
    code = 'surrogate_characters_not_allowed'
    
    def __call__(self, value):
        """Validate value does not contain surrogate characters."""

Validator Usage Examples

from rest_framework import serializers
from rest_framework.validators import UniqueValidator, UniqueTogetherValidator

class BookSerializer(serializers.ModelSerializer):
    # Unique field validator
    isbn = serializers.CharField(
        validators=[UniqueValidator(queryset=Book.objects.all())]
    )
    
    class Meta:
        model = Book
        fields = ['title', 'isbn', 'author', 'publication_year']
        
        # Unique together validator
        validators = [
            UniqueTogetherValidator(
                queryset=Book.objects.all(),
                fields=['title', 'author'],
                message="Book with this title and author already exists."
            )
        ]

# Unique for date validator
class EventSerializer(serializers.ModelSerializer):
    class Meta:
        model = Event
        fields = ['name', 'venue', 'date']
        validators = [
            UniqueForDateValidator(
                queryset=Event.objects.all(),
                field='name',
                date_field='date',
                message="Event name must be unique per date."
            )
        ]

# Custom validator function
def validate_isbn_format(value):
    """Validate ISBN format (basic example)."""
    if not value.replace('-', '').isdigit():
        raise serializers.ValidationError("ISBN must contain only digits and hyphens")
    return value

class BookSerializer(serializers.Serializer):
    isbn = serializers.CharField(validators=[validate_isbn_format])

Usage Examples

Basic Field Usage

from rest_framework import serializers

class BookSerializer(serializers.Serializer):
    title = serializers.CharField(max_length=200)
    isbn = serializers.CharField(max_length=13, min_length=13)
    publication_date = serializers.DateField()
    pages = serializers.IntegerField(min_value=1, max_value=10000)
    price = serializers.DecimalField(max_digits=6, decimal_places=2)
    is_available = serializers.BooleanField(default=True)
    
    # Custom validation
    def validate_isbn(self, value):
        if not value.isdigit():
            raise serializers.ValidationError("ISBN must contain only digits")
        return value
    
    def validate(self, data):
        if data['publication_date'] > timezone.now().date():
            raise serializers.ValidationError("Publication date cannot be in future")
        return data

Complex Field Types

class AuthorSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=100)
    email = serializers.EmailField()
    website = serializers.URLField(required=False)
    bio = serializers.CharField(allow_blank=True)
    
class BookSerializer(serializers.Serializer):
    # Nested object
    author = AuthorSerializer()
    
    # List of strings
    tags = serializers.ListField(
        child=serializers.CharField(max_length=50),
        allow_empty=False,
        max_length=5
    )
    
    # Dictionary with string values
    metadata = serializers.DictField(
        child=serializers.CharField(),
        allow_empty=True
    )
    
    # JSON field
    settings = serializers.JSONField(default=dict)
    
    # Choice field
    genre = serializers.ChoiceField(choices=[
        ('fiction', 'Fiction'),
        ('non-fiction', 'Non-Fiction'),
        ('mystery', 'Mystery'),
    ])
    
    # File upload
    cover_image = serializers.ImageField(required=False)

Method Fields and Custom Logic

class BookSerializer(serializers.ModelSerializer):
    # Computed field using method
    full_title = serializers.SerializerMethodField()
    
    # Read-only field
    created_by = serializers.ReadOnlyField(source='owner.username')
    
    # Hidden field with default
    created_at = serializers.HiddenField(default=timezone.now)
    
    # Current user default
    owner = serializers.HiddenField(default=serializers.CurrentUserDefault())
    
    class Meta:
        model = Book
        fields = ['id', 'title', 'author', 'full_title', 'created_by', 'owner']
    
    def get_full_title(self, obj):
        return f"{obj.title} by {obj.author.name}"

Custom Validation

from rest_framework import serializers

def validate_even_number(value):
    if value % 2 != 0:
        raise serializers.ValidationError("Must be an even number")
    return value

class CustomFieldSerializer(serializers.Serializer):
    # Field-level validator
    even_number = serializers.IntegerField(validators=[validate_even_number])
    
    # Custom field validation method
    def validate_title(self, value):
        if 'forbidden' in value.lower():
            raise serializers.ValidationError("Title contains forbidden word")
        return value
    
    # Object-level validation
    def validate(self, data):
        if data.get('start_date') and data.get('end_date'):
            if data['start_date'] >= data['end_date']:
                raise serializers.ValidationError("End date must be after start date")
        return data

Install with Tessl CLI

npx tessl i tessl/pypi-djangorestframework

docs

auth-permissions.md

content-negotiation.md

decorators.md

fields-validation.md

generic-views.md

index.md

pagination-filtering.md

request-response.md

routers-urls.md

serializers.md

status-exceptions.md

testing.md

views-viewsets.md

tile.json