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/
。在这种情况下,您可以仅将APIView
与get()
方法一起使用。 以上是关于django rest框架-如何在根级别停止子重复的主要内容,如果未能解决你的问题,请参考以下文章
当父记录存在时,如何在 django rest 框架的子序列化程序中设置外键值
如何在 Django REST 框架中为多对多字段定义“IsOwner”自定义权限?