django rest框架-如何在根级别停止子重复

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了django rest框架-如何在根级别停止子重复相关的知识,希望对你有一定的参考价值。

我正在使用django的嵌套自引用对象,并且具有以下Category模型

class CategoryManager(models.Manager):
    def all(self):
        qs = super(CategoryManager, self).filter(parent=None)
        return qs

class Category(models.Model):
    name = models.CharField(max_length=250)
    slug = models.SlugField(max_length=255, unique=True)
    description = models.TextField(blank=True)
    # description_json = JSONField(blank=True, default=dict)
    parent = models.ForeignKey(
        "self", null=True, blank=True, related_name="sub_category", on_delete=models.CASCADE
    )
    background_image = models.ImageField(
        upload_to="category-backgrounds", blank=True, null=True
    )

    objects = CategoryManager

对于递归表示,我在序列化器之后应用

class RecursiveSerializer(serializers.Serializer):
    def to_representation(self, value):
        serializer = self.parent.parent.__class__(value, context=self.context)
        return serializer.data

class CategoryListSerializer(ModelSerializer): 
    sub_category = RecursiveSerializer(many=True, read_only=True)

    class Meta:
        model = Category
        fields = (
            # 'url',
            'name',
            'slug',
            'description',
            'parent',
            'background_image',
            'sub_category'
        )

和查看,

class CategoryListAPIView(ListAPIView):
    queryset = Category.objects.all()
    serializer_class = CategoryListSerializer

它产生以下结果。

[
    {
        "name": "Food",
        "slug": "food",
        "description": "",
        "parent": null,
        "background_image": null,
        "background_image_alt": "",
        "sub_category": [
            {
                "name": "Rice",
                "slug": "rice",
                "description": "",
                "parent": 20,
                "background_image": null,
                "background_image_alt": "",
                "sub_category": []
            }
        ]
    },
    {
        "name": "Rice",
        "slug": "rice",
        "description": "",
        "parent": 20,
        "background_image": null,
        "background_image_alt": "",
        "sub_category": []
    }
]

这里父类别Food有一个子类别Rice很好,但是问题是子类别Rice在根级别重复,我该如何阻止它。

答案
尝试在ViewSet级别向查询集添加parent=None

class CategoryListAPIView(ListAPIView): queryset = Category.objects.filter(parent=None) serializer_class = CategoryListSerializer

使用递归序列化器是一个聪明的解决方案!唯一的问题是它将生成查询的[[lots。根据您的数据库,您可能会有更好的选择:

使用递归CTE(a very good blog on it,直接从postgres返回json)

    一次查询所有记录(如果它是一个小表),在python中构建树,然后直接返回响应。缓存响应,并在发生更新/插入时使缓存记录无效。
  • 注意:
  • 如果您不支持详细视图(ListApiView)和过滤/分页/排序,则没有充分的理由使用/view/:pk/。在这种情况下,您可以仅将APIViewget()方法一起使用。
  • 以上是关于django rest框架-如何在根级别停止子重复的主要内容,如果未能解决你的问题,请参考以下文章

    当父记录存在时,如何在 django rest 框架的子序列化程序中设置外键值

    Django rest框架在不同文件上记录不同级别

    如何在 Django REST 框架中为多对多字段定义“IsOwner”自定义权限?

    Django - 通过 websocket 在事件上重复发送 API 调用结果(REST 框架 + 通道)

    Django REST API:使特定权限级别的字段只读

    如何在 django rest 框架中访问获取请求数据