在Django的查询集中总结一个字段

Posted

技术标签:

【中文标题】在Django的查询集中总结一个字段【英文标题】:Sum up a field in the queryset in Django 【发布时间】:2019-01-04 09:03:48 【问题描述】:

models.py

class QaCommission(models.Model):
    user = models.ForeignKey(PlUser, on_delete=models.CASCADE, blank=True, null=True, related_name='user_commission')
    ref = models.ForeignKey(PlUser, on_delete=models.CASCADE, blank=True, null=True, related_name='ref_commission')
    price = models.FloatField(blank=True, null=True)
    pct = models.FloatField(blank=True, null=True)
    commission = models.FloatField(blank=True, null=True)
    status = models.IntegerField(blank=True, null=True, default=0)

序列化器.py

class QaCommissionSerializer(serializers.ModelSerializer):
    class Meta:
        model = QaCommission
        fields = '__all__'

views.py

class QaCommissionList(viewsets.ModelViewSet):
    queryset = QaCommission.objects.all()
    serializer_class = QaCommissionSerializer

如果我们在此视图中过​​滤 ref=60,结果显示如下:


"count": 18,
"next": "http://127.0.0.1:8008/api/qacommission/?ref=60&page=2",
"previous": null,
"results": [
    
        "id": 1,
        "price": 20.0,
        "pct": 0.1,
        "commission": 2.0,
        "status": 1,
        "user": 7,
        "ref": 60
    ,
    
        "id": 2,
        "price": 10.0,
        "pct": 0.1,
        "commission": 1.0,
        "status": 1,
        "user": 7,
        "ref": 60
    ,
    ......
    ......
    ......
    
        "id": 10,
        "price": 15.0,
        "pct": 0.1,
        "commission": 1.5,
        "status": 1,
        "user": 7,
        "ref": 60
    
]

我想对结果中的所有“commission”字段求和,并将总和附加到原始查询集(可能在“count”旁边:18),如上图,有18个commission需要计算。

我该如何实现呢?需要您的帮助,谢谢!

【问题讨论】:

from django.db.models import Sum \n qs = QaCommission.objects.filter().aggregate(commission_sum=Sum('commission')) sum is stored in qs['commission_sum'] 也许这个https://***.com/questions/31920853/aggregate-and-other-annotated-fields-in-django-rest-framework-serializers会回答你的问题 在模型类中添加类方法可以帮助你总结出你的queryset结果的commision值。 【参考方案1】:

尝试覆盖ModelViewsetlist()方法为,

class QaCommissionList(viewsets.ModelViewSet):
    queryset = QaCommission.objects.all()
    serializer_class = QaCommissionSerializer

    def list(self, request, *args, **kwargs):
        response = super().list(request, *args, **kwargs)
        response.data['sum'] = sum([data.get('commission', 0) for data in response.data['results']])
        return response

这个答案总结了commision 来自特定页面并显示它 更新

from django.db.models import Sum


class QaCommissionList(viewsets.ModelViewSet):
    queryset = QaCommission.objects.all()
    serializer_class = QaCommissionSerializer

    def list(self, request, *args, **kwargs):
        response = super().list(request, *args, **kwargs)
        if 'ref' in request.GET and request.GET['ref']:
            response.data['sum'] = QaCommission.objects.filter(ref=int(request.GET['ref'])
                                                               ).aggregate(sum=Sum('commission'))['sum']
        return response

上面的答案将返回 commission 列 w.r.t 的整数和过滤器(不考虑分页) 感谢@bruno 提到这样一个有效的观点

【讨论】:

不使用SQL数据库有什么意义? 我认为他需要,sum(commission)来自当前页面 很棒的答案!我需要所有页面的总和,但我也从当前的第一页中受益。谢谢!

以上是关于在Django的查询集中总结一个字段的主要内容,如果未能解决你的问题,请参考以下文章

Django:更改查询集中所有对象的字段值

Django Newbie - 使用多字段表单,如何消除查询集中的空字段

django模板变量从查询集中构建表的字段数

Django:如何根据来自行的数据和来自另一个模型的数据将聚合字段添加到查询集中?

基于 Django 查询集中外键字段的 .count() 进行过滤

Django 在不使用字段查找的情况下从查询集中排除特定实例