Please wait...
In this post, you're going to learn how to get nested data from the Django REST framework.
Django REST Framework uses Serializer class that converts Django queryset to JSON with Python datatypes
But if you define Serializer class with the nested class so it will return data in nested format but it'll need the same format for POST request data.
Let me add a sample for this.
models.py
from django.db import models
class Category(models.Model):
title = models.CharField("Title", max_length=255)
class Tag(models.Model):
title = models.CharField("Title", max_length=255)
class Post(models.Model):
title = models.CharField("Title", max_length=255)
description = models.TextField()
category = models.ForeignKey(Category, on_delete=models.CASCADE)
tags = models.ManyToManyField(Tag)
Above we have 3 models that represent blogs models
serializer.py
from rest_framework import serializers
from .models import Category, Tag, Post
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = "__all__"
class TagSerializer(serializers.ModelSerializer):
class Meta:
model = Tag
fields = "__all__"
class PostSerializer(serializers.ModelSerializer):
category = CategorySerializer()
tags = TagSerializer(many=True)
class Meta:
model = Post
fields = "__all__"
views.py
from rest_framework.viewsets import ModelViewSet
from .models import Post
from .serializer import PostSerializer
class PostViewSet(ModelViewSet):
serializer_class = PostSerializer
queryset = Post.objects.all()
As you can see in PostSerializer, it's using nested serializers CategorySerializer and TagSerializer so when we POST data through API, data should be like:
{
title: "How to get nested data in Django REST Framework",
description: "Lorem Ipsum",
category: {
"title": "Django"
},
tags: [
{
"title": "Django"
},
{
"title": "Django rest framework"
}
]
}
and in this JSON Category and Tags will create and GET response will be the same from API in GET request.
We need to follow below point:
1 Create NestedSerializerMixin :
class NestedSerializerMixin(ModelViewSet):
read_serializer_class = None
def get_serializer_class(self):
if self.request.method.lower() == "get":
return self.read_serializer_class
return self.serializer_class
2. Update PostSerializer and Create a new serializer for Response only
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = "__all__"
class NestedPostSerializer(serializers.ModelSerializer):
category = CategorySerializer()
tags = TagSerializer(many=True)
class Meta:
model = Post
fields = "__all__"
3. Add Attribute in view read_serializer_class:
class PostViewSet(NestedSerializerMixin):
serializer_class = PostSerializer
queryset = Post.objects.all()
read_serializer_class = NestedPostSerializer
Now we have changed the Serializer Class for POST and GET request.
so we can post data like:
{
title: "How to get nested data in Django REST Framework",
description: "Lorem Ipsum",
category: 1,
tags: [
1,
2
]
}
Here Category: 1 means already exist category pk, same for tags with an Array because tags have ManyToManyField
Now GET API response will show nested data
{
title: "How to get nested data in Django REST Framework",
description: "Lorem Ipsum",
category: {
"title": "Django"
},
tags: [
{
"title": "Django"
},
{
"title": "Django rest framework"
}
]
}
We can import NestedSerializerMixin in Django REST framework Views when we need to GET and POST different data
Previous Post arrow_back
Custom Django data migrations with RunPython ClassNext Post arrow_forward
Save and Get objects using Python pickle module