Serializers
ModelSerializer
from rest_framework import serializers
from .models import Post
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = '__all__'
# fields = ['id', 'title']
# exclude = ['slug']
Nested Serializers (Read-Only)
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = ['id', 'name']
class PostSerializer(serializers.ModelSerializer):
category = CategorySerializer(read_only=True)
class Meta:
model = Post
fields = ['id', 'title', 'category']
Field-Level Validation
class PostSerializer(serializers.Serializer):
def validate_title(self, value):
if 'django' not in value.lower():
raise serializers.ValidationError("Title must contain 'Django'")
return value
Object-Level Validation
class PostSerializer(serializers.Serializer):
def validate(self, data):
if data['is_published'] and not data['published_at']:
raise serializers.ValidationError("Published posts must have a date")
return data
SerializerMethodField (Computed Fields)
class PostSerializer(serializers.ModelSerializer):
content_length = serializers.SerializerMethodField()
def get_content_length(self, obj):
return len(obj.content)
class Meta:
model = Post
fields = ['title', 'content_length']
Custom Field Source
class PostSerializer(serializers.ModelSerializer):
author_name = serializers.CharField(source='author.username', read_only=True)
class Meta:
model = Post
fields = ['title', 'author_name']
Writable Nested Serializers
class PostSerializer(serializers.ModelSerializer):
category = CategorySerializer()
def create(self, validated_data):
category_data = validated_data.pop('category')
category, _ = Category.objects.get_or_create(**category_data)
return Post.objects.create(category=category, **validated_data)