Nested Serializers0%

Nested Serializers

Beginner12 min read•Updated: Jul 11, 2026
Study MaterialsCheatsheet

DRF Nested Serializers and Writable Nested Representations

In relational domain models, parent and child records are tightly coupled. For example, an Invoice contains multiple InvoiceItems, or an Order contains multiple OrderLineItems. While reading nested data is straightforward in DRF, writable nested serializers (creating or updating parent and child objects in a single API request) require implementing custom create() and update() methods.


1. Read-Only Nested Serialization

Embedding related child representations in read responses is accomplished by nesting child serializers:

Python
# billing/serializers.py
from rest_framework import serializers
from .models import Invoice, InvoiceItem
 
class InvoiceItemSerializer(serializers.ModelSerializer):
class Meta:
model = InvoiceItem
fields = ["id", "description", "quantity", "unit_price", "total_price"]
 
class InvoiceDetailSerializer(serializers.ModelSerializer):
# Read-only nested array of items
items = InvoiceItemSerializer(many=True, read_only=True)
 
class Meta:
model = Invoice
fields = ["id", "invoice_number", "customer_name", "created_at", "items"]

2. The Writable Nested Challenge

By default, calling serializer.save() on a nested serializer with writable fields raises an error:

"The .create() method does not support writable nested fields by default. Write an explicit .create() on this serializer."

Because Django models cannot guess how you wish to handle relational children (whether to update, delete, or create new rows), you must explicitly implement create() and update().


3. Implementing Writable create()

Python
# billing/serializers.py
class InvoiceItemWriteSerializer(serializers.ModelSerializer):
class Meta:
model = InvoiceItem
fields = ["description", "quantity", "unit_price"]
 
class InvoiceCreateSerializer(serializers.ModelSerializer):
# Writable nested items array
items = InvoiceItemWriteSerializer(many=True)
 
class Meta:
model = Invoice
fields = ["invoice_number", "customer_name", "items"]
 
def create(self, validated_data):
# 1. Pop nested child data out of validated_data
items_data = validated_data.pop("items", [])
 
# 2. Create the parent Invoice instance
invoice = Invoice.objects.create(**validated_data)
 
# 3. Create each child InvoiceItem bound to parent invoice
for item_data in items_data:
InvoiceItem.objects.create(invoice=invoice, **item_data)
 
return invoice

4. Implementing Writable update()

Updating nested records requires handling three possibilities:

  1. 1
    Existing items that were modified.
  2. 2
    New items added to the array.
  3. 3
    Items omitted from the array that should be deleted.
Python
def update(self, instance, validated_data):
items_data = validated_data.pop("items", None)
 
# Update parent fields
instance.invoice_number = validated_data.get("invoice_number", instance.invoice_number)
instance.customer_name = validated_data.get("customer_name", instance.customer_name)
instance.save()
 
if items_data is not None:
# Simple strategy: Replace existing items with incoming set
instance.items.all().delete()
for item_data in items_data:
InvoiceItem.objects.create(invoice=instance, **item_data)
 
return instance

5. Client JSON Request Body

The client can now create the complete parent and children in a single HTTP request:

HTTP
POST /api/v1/invoices/ HTTP/1.1
Content-Type: application/json
 
{
"invoice_number": "INV-2026-0042",
"customer_name": "Acme Global Corp",
"items": [
{ "description": "Cloud Hosting Enterprise", "quantity": 1, "unit_price": 1200.00 },
{ "description": "DevOps Maintenance", "quantity": 10, "unit_price": 150.00 }
]
}

Interactive Quiz

Practice Quiz

Question 1
Why does DRF raise an error if you attempt to save a ModelSerializer with writable nested fields without defining .create()?
Question 2
What Python method removes the nested list from validated_data so the parent model can be instantiated cleanly?
Question 3
What is a primary performance consideration when reading deeply nested serializers?
Question 4
How do you mark a nested serializer as strictly read-only?
Question 5
What is the benefit of writable nested serializers for API clients?
Next Lesson

Handling Related Objects

Continue learning with hands-on practice, examples, and exercises in the upcoming topic.

Related Lessons

Practice Quiz

Test your understanding of this lesson with 5 questions. Each question has one correct answer.

PrevNext