Django: 通过查询计算列值之和

我有个模特

class ItemPrice( models.Model ):
price = models.DecimalField ( max_digits = 8, decimal_places=2 )
....

我尝试这样计算这个查询集中 price的总和:

items = ItemPrice.objects.all().annotate(Sum('price'))

这个查询有什么问题吗? 或者还有其他方法来计算 price列的和吗?

我知道这可以通过在查询集上使用 for 循环来完成,但是我需要一个优雅的解决方案。

谢谢!

139312 次浏览

你可能在找 aggregate

from django.db.models import Sum


ItemPrice.objects.aggregate(Sum('price'))
# returns {'price__sum': 1000} for example

Annotate 在结果中添加了一个字段:

>> Order.objects.annotate(total_price=Sum('price'))
<QuerySet [<Order: L-555>, <Order: L-222>]>


>> orders.first().total_price
Decimal('340.00')

总计返回一个查询结果的结果:

>> Order.objects.aggregate(total_price=Sum('price'))
{'total_price': Decimal('1260.00')}

使用 .aggregate(Sum('column'))['column__sum']参考我下面的例子

sum = Sale.objects.filter(type='Flour').aggregate(Sum('column'))['column__sum']

使用 配置文件剖析器,我发现在我的开发环境中,对列表的值进行求和比使用 Sum()进行聚合更有效(更快)。 例如:

sum_a = sum([item.column for item in queryset]) # Definitely takes more memory.
sum_b = queryset.aggregate(Sum('column')).get('column__sum') # Takes about 20% more time.

我在不同的环境下测试了这个,似乎使用 aggregate总是需要更长的时间才能产生相同的结果。尽管我怀疑在内存方面使用它而不是汇总一个列表可能会有一些好处。

以前的答案都很好,而且,你可能会得到一行香草代码的总和..。

items = ItemPrice.objects.all()
total_price = sum(items.values_list('price', flat=True))

你也可以通过这种方式得到总和:

def total_sale(self):
total = Sale.objects.aggregate(TOTAL = Sum('amount'))['TOTAL']
return total

将“金额”替换为您要计算的模型中的列名称,并将销售额替换为您的模型名称。