自关联的表如何序列化:
表:
class Category(BaseModel):
"""
商品类别
"""
CLASSIFY_CHOICES = (
(1, '面料'),
(2, "款式"),
)
name = models.CharField(max_length=20, verbose_name='名称')
parent = models.ForeignKey('self', null=True, blank=True, related_name='subs', on_delete=models.SET_NULL, verbose_name='父类别')
classify = models.SmallIntegerField(default=1, choices=CLASSIFY_CHOICES, verbose_name='所属商品分类')
desc = models.CharField(default='', max_length=200, verbose_name='备注')
class Meta:
db_table = 'tb_category'
verbose_name = '面料类别'
verbose_name_plural = verbose_name
def __str__(self):
return '%s-%s-%s' % (self.id,self.get_classify_display(),self.name)
视图:
class AView(GenericAPIView):
permission_classes = [IsAuthenticated, AdminUserPermission]
def get(self, request, *args, **kwargs):
query = Category.objects.filter(classify=1, parent_id__isnull=True).order_by('id')
serializer = ASerializer(query, many=True)
return APIResponse.success(data=serializer.data)
序列化器:
class ASerializer(serializers.ModelSerializer):
subs = serializers.SerializerMethodField()
class Meta:
model = Category
fields = ('id', 'name', 'parent_id', 'parent', 'subs')
def get_subs(self, obj):
if obj.subs:
return ASerializer(obj.subs, many=True).data
else:
return None
但是这种有一个缺点,就是有多少条数据就查询多少次数据库,所以不建议数据特别多的使用,最好先把数据给查询出来,然后再排列组合就像下面的一样:
视图:
def change_comments(data, parent_id):
"""
data: 序列化后的数据
parent_id: 数据库中自关联的字段
"""
list = []
tree = {}
root = ''
p_id = ''
for data_dict in data:
#将data循环,然后加入一个dict中,key为每条数据的ID,val对应为整条数据
tree[data_dict["id"]] = data_dict
for data_dict in data:
if data_dict[parent_id] == None:
root = tree[data_dict["id"]] #i.di为tree里的key,将key对应的val取出
list.append(root)
else:
p_id = data_dict[parent_id]
# 判断父级是否有孩子字段(childlist),如果有将当前数据加入,如果没有添加(childlist)后再加入
if "sub" not in tree[p_id]:
tree[p_id]['sub'] = []
tree[p_id]["sub"].append(tree[data_dict["id"]])
return list
class AView(GenericAPIView):
permission_classes = [IsAuthenticated, AdminUserPermission]
def get(self, request, *args, **kwargs):
query = Category.objects.filter(classify=1).order_by('id')
serializer = ASerializer(query, many=True)
data = change_comments(serializer.data, 'parent_id')
return APIResponse.success(data=data)
序列化器:
class ASerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = ('id', 'name', 'parent_id', 'parent')