我有一个类别模型,它是 MPTT 模型。它是 m2m 到组,我需要序列化具有相关计数的树,想象我的类别树是这样的:
Root (related to 1 group)
- Branch (related to 2 groups)
- Leaf (related to 3 groups)
...
所以序列化的输出将如下所示:
{
id: 1,
name: 'root1',
full_name: 'root1',
group_count: 6,
children: [
{
id: 2,
name: 'branch1',
full_name: 'root1 - branch1',
group_count: 5,
children: [
{
id: 3,
name: 'leaf1',
full_name: 'root1 - branch1 - leaf1',
group_count: 3,
children: []
}]
}]
}
这是我目前超级低效的实现:
Model
class Category(MPTTModel):
name = ...
parent = ... (related_name='children')
def get_full_name(self):
names = self.get_ancestors(include_self=True).values('name')
full_name = ' - '.join(map(lambda x: x['name'], names))
return full_name
def get_group_count(self):
cats = self.get_descendants(include_self=True)
return Group.objects.filter(categories__in=cats).count()
View
class CategoryViewSet(ModelViewSet):
def list(self, request):
tree = cache_tree_children(Category.objects.filter(level=0))
serializer = CategorySerializer(tree, many=True)
return Response(serializer.data)
串行器
class RecursiveField(serializers.Serializer):
def to_native(self, value):
return self.parent.to_native(value)
class CategorySerializer(serializers.ModelSerializer):
children = RecursiveField(many=True, required=False)
full_name = serializers.Field(source='get_full_name')
group_count = serializers.Field(source='get_group_count')
class Meta:
model = Category
fields = ('id', 'name', 'children', 'full_name', 'group_count')
这是可行的,但也会通过大量的查询来访问数据库,而且还有其他关系,而不仅仅是组。有没有办法提高效率?如何编写自己的序列化器?