Django:通过查询计算列值的总和


92

我有一个模特

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

我试图这样做来计算此查询price集中的总和:

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

这个查询有什么问题?还是有其他方法可以计算price列的总和?

我知道可以通过在queryset上使用for循环来完成此操作,但我需要一个优雅的解决方案。

谢谢!


这回答了你的问题了吗?Django SUM查询?
Flimm

Answers:


196

您可能正在寻找 aggregate

from django.db.models import Sum

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

1
如何获得价格等于5000的总计数?
Anuj Sharma

6
记住返回字典,而不是浮点数/整数,例如{'price__sum':1000}。可以使用yourdict['price__sum']
乔什(Josh)

35

注释为结果添加了一个字段:

>> 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')}

感谢您显示如何指定将key和存储value到其中。
MikeyE

32

.aggregate(Sum('column'))['column__sum']在下面使用冷藏柜我的示例

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

5

使用cProfile事件探查器,我发现在开发环境中,对列表的值求和比使用进行聚合更有效(更快)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它总是花费更长的时间才能产生相同的结果。尽管我怀疑使用内存而不是对列表求和可能在内存方面有优势。


1
或者,使用生成器表达式而不是列表:sum_a = sum(item.column for item in queryset)。唯一的不同是被删除[]的。这样可以节省在sum()迭代之前计算整个列表的内存空间。
代码学徒
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.