Last modified: Mar 11, 2025 By Alexander Williams
Django Rest Framework Nested Serializers Guide
Django Rest Framework (DRF) is a powerful tool for building APIs. One of its key features is the ability to handle related models using nested serializers. This guide will walk you through the process.
What Are Nested Serializers?
Nested serializers allow you to include related models within a single API response. This is useful when you need to retrieve data from multiple models in one request. For example, you might want to include a user's profile information along with their posts.
Setting Up Your Models
Let's start by defining two related models: Author and Book. Each author can have multiple books.
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
bio = models.TextField()
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.ForeignKey(Author, related_name='books', on_delete=models.CASCADE)
Creating Serializers
Next, we need to create serializers for these models. We'll use ModelSerializer
for both models. The BookSerializer
will be nested within the AuthorSerializer
.
from rest_framework import serializers
from .models import Author, Book
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = ['id', 'title']
class AuthorSerializer(serializers.ModelSerializer):
books = BookSerializer(many=True, read_only=True)
class Meta:
model = Author
fields = ['id', 'name', 'bio', 'books']
Using Nested Serializers in Views
Now that we have our serializers, we can use them in our views. Here's an example of how to retrieve an author along with their books.
from rest_framework import generics
from .models import Author
from .serializers import AuthorSerializer
class AuthorDetailView(generics.RetrieveAPIView):
queryset = Author.objects.all()
serializer_class = AuthorSerializer
Example Output
When you make a GET request to the AuthorDetailView
, you'll receive a JSON response that includes the author's details and a list of their books.
{
"id": 1,
"name": "J.K. Rowling",
"bio": "British author best known for the Harry Potter series.",
"books": [
{
"id": 1,
"title": "Harry Potter and the Philosopher's Stone"
},
{
"id": 2,
"title": "Harry Potter and the Chamber of Secrets"
}
]
}
Handling Nested Writes
By default, nested serializers are read-only. If you need to handle nested writes, you'll need to override the create
and update
methods in your serializer. This allows you to create or update related models along with the main model.
class AuthorSerializer(serializers.ModelSerializer):
books = BookSerializer(many=True)
class Meta:
model = Author
fields = ['id', 'name', 'bio', 'books']
def create(self, validated_data):
books_data = validated_data.pop('books')
author = Author.objects.create(**validated_data)
for book_data in books_data:
Book.objects.create(author=author, **book_data)
return author
def update(self, instance, validated_data):
books_data = validated_data.pop('books')
instance.name = validated_data.get('name', instance.name)
instance.bio = validated_data.get('bio', instance.bio)
instance.save()
# Update or create books
for book_data in books_data:
book_id = book_data.get('id', None)
if book_id:
book = Book.objects.get(id=book_id, author=instance)
book.title = book_data.get('title', book.title)
book.save()
else:
Book.objects.create(author=instance, **book_data)
return instance
Conclusion
Nested serializers in Django Rest Framework are a powerful way to handle related models. They allow you to include related data in a single API response, making your API more efficient and easier to use. By following this guide, you should be able to implement nested serializers in your own projects.
For more advanced topics, check out our guides on Django Rest Framework Serializers and ViewSets and Routers.