使用Django ORM跨过滤的查询集聚合属性值

时间:2016-11-28 11:25:47

标签: django

django queryset包含用户上传的照片及其相应的upvotes(来自观看者)。

我需要运行一个查询,它返回一起添加的所有投票。有没有办法使用ORM返回总票数?我认为它会比我现在这样做更快(性能对我来说很重要)。

目前我正在尝试以下方法:

yesterday = datetime.utcnow() - timedelta(hours = 24)
photos = Photo.objects.filter(upload_time__gte=yesterday)
cumulative_votes = 0
for photo in photos:
    cumulative_votes += photo.total_votes

2 个答案:

答案 0 :(得分:1)

你需要使用Django db的Sum或Count函数, 像这样:

from django.db.models import Count, Sum
yesterday = datetime.utcnow() - timedelta(hours = 24)

photos = Photo.objects.filter(upload_time__gte=yesterday).aggregate(total_votes=Count('total_votes'))
photo_sum = photos['total_votes']

from django.db.models import Count, Sum
yesterday = datetime.utcnow() - timedelta(hours = 24)

photos = Photo.objects.filter(upload_time__gte=yesterday).aggregate(total_votes=Sum('total_votes'))
photo_sum = photos['total_votes']

感谢。

答案 1 :(得分:1)

这是一个单行:

total_vote_sum = Photo.objects.filter(filter_stuff).aggregate(Sum("total_votes"))["total_votes__sum"]

引自: https://docs.djangoproject.com/es/1.10/topics/db/aggregation/#generating-aggregates-over-a-queryset

aggregate()是QuerySet的终止子句,在调用时,返回名称 - 值对的字典。该名称将根据字段名称和聚合函数自动生成。

所以queryset.aggregate(Sum('field'))将返回如下字典:
{"field__sum": 'result'}

考虑到这一点,我们可以直接得到我们想要的结果:

result = queryset.aggregate(Sum('field'))['field__sum']