Reputation: 103
I have a Django model that is hierarchical using django-mptt, which looks like:
class UOMCategory(MPTTModel, BaseModel):
"""
This represents categories of different unit of measurements.
"""
name = models.CharField(max_length=50, unique=True)
description = models.CharField(max_length=50, unique=True)
parent = TreeForeignKey('self', null=True, blank=True, related_name='%(app_label)s_%(class)s_sub_uom_categories')
The problem now is I created a REST API using Django REST Framework; how do I make sure that parent field returns serialized data?
Here is the Model Serializer:
class UOMCategorySerializer(BaseModelSerializer):
"""
REST API Serializer for UOMCategory model
"""
class Meta:
model = UOMCategory
Upvotes: 7
Views: 8884
Reputation: 1155
Simple DRF API view using MPTT cache and DRF serializer.
from rest_framework import serializers
from rest_framework.generics import GenericAPIView
from rest_framework.response import Response
from events.models import Category
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = (
"name",
"slug",
)
class CategoryTreeView(GenericAPIView):
serializer_class = CategorySerializer
def get(self, request, *args, **kwargs):
root_nodes = Category.objects.all().get_cached_trees()
data = []
for n in root_nodes:
data.append(self.recursive_node_to_dict(n))
return Response(data)
def recursive_node_to_dict(self, node):
result = self.get_serializer(instance=node).data
children = [self.recursive_node_to_dict(c) for c in node.get_children()]
if children:
result["children"] = children
return result
Upvotes: 1
Reputation: 713
In DRF you can use a serializer as a field in another serializer. However, recursion is not possible.
Tom Christie posted a solution on another question (Django rest framework nested self-referential objects). His solution will also work with your problem.
In your UOMCategorySerializer.Meta class you specify the fields you want to use, also list the parent and/or children field(s) there. Then you use Tom Christies solution.
In your case this would give:
class UOMCategorySerializer(ModelSerializer):
class Meta:
model = UOMCategory
fields = ('name', 'description', 'parent', 'children')
Tom Christies solution: By specifying what field to use for parent and/or children, you avoid using too much (and possibily endless) recursion:
UOMCategorySerializer.base_fields['parent'] = UOMCategorySerializer()
UOMCategorySerializer.base_fields['children'] = UOMCategorySerializer(many=True)
The above works for me in a similar situation.
Upvotes: 8