In Django REST Framework (DRF), relationships between models—such as ForeignKey, OneToOneField, and ManyToManyField—can be represented as nested structures using serializers.
DRF provides a simple way to serialize related objects using the depth
option in a ModelSerializer
. It automatically includes nested relationships up to a specified depth.
In this article, we’ll cover:
-
✅ What is the
depth
option -
How to use it in serializers
-
Examples with models and output
-
⚠️ Limitations and when to avoid it
-
✅ Best practices and tips
What is the depth
Option?
The depth
option is a Meta class attribute in a ModelSerializer
that tells DRF how many levels deep it should automatically serialize related models.
-
depth = 1
includes directly related fields (ForeignKey, OneToOne, ManyToMany). -
depth = 2
goes one level deeper (related fields of related fields), and so on.
Syntax
class MySerializer(serializers.ModelSerializer):
class Meta:
model = MyModel
fields = '__all__'
depth = 1
Example: One-to-Many Relationship
Models:
# models.py
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
Serializer with depth = 1
# serializers.py
from rest_framework import serializers
from .models import Author, Book
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = '__all__'
depth = 1
Response Output
{
"id": 1,
"title": "Django Deep Dive",
"author": {
"id": 3,
"name": "Jane Doe"
}
}
This is equivalent to writing a nested serializer manually:
class AuthorSerializer(serializers.ModelSerializer):
class Meta:
model = Author
fields = ['id', 'name']
class BookSerializer(serializers.ModelSerializer):
author = AuthorSerializer()
...
Going Deeper: depth = 2
If Author had a relationship, say Country
, setting depth = 2
would serialize that as well.
{
"title": "Book Title",
"author": {
"name": "Jane",
"country": {
"name": "USA"
}
}
}
⚠️ Limitations of depth
While convenient, depth
has several drawbacks:
Limitation | Explanation |
---|---|
❌ Read-only | You cannot write to nested fields using depth —use nested serializers for that |
❌ No control | You can’t customize the fields of the nested serializers |
❌ Risk of over-serialization | Setting depth > 1 can produce large, slow responses |
❌ Hard to scale | If model structure changes, deeply nested serialization can break or bloat your API |
✅ When to Use depth
Use depth
if:
-
You need quick, read-only nested output
-
You want to prototype your API
-
Your relationships are simple and not deeply nested
Best Practices
Best Practice | Reason |
---|---|
✅ Limit depth to 1 |
Keeps responses performant and readable |
✅ Switch to nested serializers for customization | Gives you more flexibility and validation |
✅ Avoid using depth in large production APIs |
Use explicit serializers instead |
✅ Use depth during development only |
Replace with explicit nested serializers later |
Full Working Example
models.py
class Country(models.Model):
name = models.CharField(max_length=100)
class Author(models.Model):
name = models.CharField(max_length=100)
country = models.ForeignKey(Country, on_delete=models.CASCADE)
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
serializers.py
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = '__all__'
depth = 2
API Output
{
"title": "My Book",
"author": {
"name": "Jane",
"country": {
"name": "Canada"
}
}
}
✅ Summary
Feature | What it Does |
---|---|
depth |
Automatically serializes related objects |
depth=1 |
Shows immediate relationships |
depth=2+ |
Goes deeper into nested relationships |
Use Case | Quick, read-only nested views |
Avoid When | Writing nested data or needing field-level control |
Conclusion
The depth
option is a powerful yet limited tool in DRF for quick and automatic nested serialization. While great for quick APIs or admin use, it’s best to use explicit nested serializers for production applications that require control, customization, or writable nested data.