How to serialize hierarchical relationship in Django REST

前端 未结 2 786
时光取名叫无心
时光取名叫无心 2021-02-09 07:53

I have a Django model that is hierarchical using django-mptt, which looks like:

class UOMCategory(MPTTModel, BaseModel):
    \"\"\"
        This represents categ         


        
相关标签:
2条回答
  • 2021-02-09 08:12

    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.

    0 讨论(0)
  • 2021-02-09 08:21

    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
    
    0 讨论(0)
提交回复
热议问题