【问题标题】:How to serialize hierarchical relationship in Django REST如何在 Django REST 中序列化层次关系
【发布时间】:2014-02-02 10:32:28
【问题描述】:

我有一个使用 django-mptt 分层的 Django 模型,如下所示:

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')

现在的问题是我使用 Django REST Framework 创建了一个 REST API;如何确保父字段返回序列化数据?

这是模型序列化器:

class UOMCategorySerializer(BaseModelSerializer):
    """
    REST API Serializer for UOMCategory model
    """
    class Meta:
        model = UOMCategory

【问题讨论】:

  • 如果没有更多信息,这很难回答。您可以将序列化程序代码添加到您的问题中吗?另外我想你指的是django-rest-framework.org;这可能有助于更具体地说明这一点。
  • 是的,我正在使用 Django REST 框架

标签: python django serialization django-rest-framework django-mptt


【解决方案1】:

在 DRF 中,您可以将序列化程序用作另一个序列化程序中的字段。但是,递归是不可能的。

Tom Christie 针对另一个问题 (Django rest framework nested self-referential objects) 发布了解决方案。他的解决方案也适用于您的问题。

在您的 UOMCategorySerializer.Meta 类中,您指定要使用的字段,并在其中列出父和/或子字段。然后你使用 Tom Christies 解决方案。

在您的情况下,这将给出:

class UOMCategorySerializer(ModelSerializer):
    class Meta:
        model = UOMCategory
        fields = ('name', 'description', 'parent', 'children')

Tom Christies 解决方案:通过指定用于父和/或子的字段,您可以避免使用过多(并且可能是无穷无尽的)递归:

UOMCategorySerializer.base_fields['parent'] = UOMCategorySerializer()
UOMCategorySerializer.base_fields['children'] = UOMCategorySerializer(many=True)

以上方法在类似情况下对我有用。

【讨论】:

    【解决方案2】:

    使用 MPTT 缓存和 DRF 序列化程序的简单 DRF API 视图。

    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
    

    【讨论】:

      猜你喜欢
      • 2016-10-07
      • 2015-12-13
      • 2015-03-04
      • 2016-12-18
      • 2017-10-05
      • 1970-01-01
      • 1970-01-01
      • 2021-06-12
      • 1970-01-01
      相关资源
      最近更新 更多