亲子关系建模REST API

问题描述 投票:0回答:1

我下面有一个具有父子关系的示例表。

id 家长
1
2 1
3 2
4

我必须在 UI 中将其表示为树结构。对此的最佳方法是什么?我是否从 API 中获取数据并在前端将其重组为树形层次结构?

[
    {
        "id": 1,
        "parent": null,
    },
    {
        "id": 2,
        "parent": 1,
    },
    {
        "id": 3,
        "parent": 2,
    },
    {
        "id": 4,
        "parent": null,
    }
]

API 应将响应构建为树,以便 UI 简单地使用它。

[
    {
        "id": 1,
        "parent": null,
        "children": [
            {
                "id": 2,
                "parent": 1,
                "children": [
                    {
                        "id": 3,
                        "parent": 2,
                        "children": []
                    }
                ]
            }
        ]
    },
    {
        "id": 4,
        "parent": null,
        "children": []
    }
]

如果我必须使用第二种方法之类的方法,那么最有效的方法是什么,这样就不会出现重复的条目。

我正在使用 djangorestframework 并做出反应。

rest serialization django-rest-framework django-serializer
1个回答
0
投票

您可以使用serializers.SerializerMethodField()在序列化器中自定义逻辑

型号

class FolderModel(models.Model):
    name = models.CharField(max_length=100)
    parent = models.ForeignKey('self', on_delete=models.CASCADE, related_name='children', null=True)

序列化器

class FolderSerializer(serializers.ModelSerializer):
    children = serializers.SerializerMethodField()

    def get_children(self, obj):
        """
        prevent deep recursion by set limit depth
        """

        depth = self.context.get('depth', 0)
        if 10 > depth:
            self.context['depth'] = depth + 1
            return FolderSerializer(obj.children.all(), context=self.context, many=True).data
        else:
            return []

    class Meta:
        model = FolderModel
        fields = ['id', 'name', 'name', 'parent', 'children']

查看

将过滤器

parent=None
添加到查询集中

class FolderView(viewsets.ModelViewSet):
    model = FolderModel
    queryset = FolderModel.objects.all().filter(parent=None)
    serializer_class = FolderSerializer

无论如何,如果你在视图中设置了“

queryset = FolderModel.objects.all().filter(parent=None)
” 没有机会点击“递归超出”。所以你可以直接返回序列化器

def get_children(self, obj):
    return FolderSerializer(obj.children.all(), context=self.context, many=True).data
        
© www.soinside.com 2019 - 2024. All rights reserved.