如何在DRF Viewsets中统计ForeignKey关联子对象的数量
解决方案
实现逻辑说明
- 推荐使用Django ORM的
annotate+聚合函数Count实现关联统计,一次查询即可完成所有父对象的子项统计,不会产生N+1性能问题,不需要单独获取每个Parent的id手动统计。
代码修改
1. 视图层(views.py)
首先导入Count聚合函数,删掉无用的children = Child.objects.filter()那行,修改get_queryset方法即可:
from django.db.models import Count from rest_framework import viewsets from .models import Parent from .serializers import ParentSerializer class ParentViewSet(viewsets.ModelViewSet): serializer_class = ParentSerializer def get_queryset(self): # 外键未设置related_name时,反向关联默认名为`模型名小写_set`即child_set queryset = Parent.objects.all().annotate(child_count=Count('child_set')) return queryset
如果希望反向关联名更直观,可修改models.py中Child的外键定义,添加
related_name参数:class Child(models.Model): name = models.CharField(max_length=100) parent = models.ForeignKey("Parent", on_delete=models.CASCADE, related_name="children")此时annotate写法可改为
annotate(child_count=Count('children'))
2. 序列化层(serializers.py)
给child_count字段添加read_only=True参数,避免创建/更新Parent时要求传入该统计字段:
from rest_framework import serializers from .models import Parent class ParentSerializer(serializers.ModelSerializer): child_count = serializers.IntegerField(read_only=True) class Meta: model = Parent fields = ["id", "name", "child_count"]
修改完成后接口返回的格式就和你要求的完全一致。
内容的提问来源于stack exchange,提问作者imandy
相关产品推荐
相关产品推荐

