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

brqmpdu1  于 2023-01-27  发布在  Go
关注(0)|答案(7)|浏览(266)

我有一个模型:

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

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

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

这个查询有什么问题?或者有没有其他方法来计算Sum of price列?
我知道这可以通过在queryset上使用for循环来实现,但我需要一个优雅的解决方案。
谢谢!

xqk2d5yq

xqk2d5yq1#

您可能正在查找aggregate

from django.db.models import Sum

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

0yg35tkg2#

使用.aggregate(Sum('column'))['column__sum'] reefer我的例子如下

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

bvjveswy3#

“注解”将字段添加到结果:

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

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

聚合返回一个带有请求结果的dict:

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

fwzugrvs4#

使用 cProfile profiler,我发现在我的开发环境中,对列表值求和比使用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总是需要更长的时间来产生相同的结果,尽管我怀疑使用它而不是对列表求和可能会有内存方面的优势。

93ze6v8z

93ze6v8z5#

前面的答案都很好,而且,你可以用一行香草代码得到那个总数...

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

tzxcd3kk6#

您也可以通过以下方式获得总和:

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

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

5w9g7ksd

5w9g7ksd7#

您需要使用aggregate()和Sum()来计算price列的和,如下所示。* 使用all()的查询等同于不使用all()的查询,如下所示:

from django.db.models import Sum

print(ItemPrice.objects.all().aggregate(Sum('price')))
print(ItemPrice.objects.aggregate(Sum('price')))

然后,在控制台上输出以下字典:

{'price__sum': Decimal('150.00')}
{'price__sum': Decimal('150.00')}

并且,您可以将price列的默认键price__sum更改为priceSum,如下所示:

from django.db.models import Sum
                                        # ↓ Here
print(ItemPrice.objects.all().aggregate(priceSum=Sum('price')))
print(ItemPrice.objects.aggregate(priceSum=Sum('price')))
                                  # ↑ Here

然后,默认密钥更改如下:

{'priceSum': Decimal('150.00')}
{'priceSum': Decimal('150.00')}

相关问题