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

发布于 2024-12-22 10:29:05 字数 385 浏览 1 评论 0原文

我有一个模型:

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

我尝试用它来计算此查询集中的 price 总和:

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

此查询出了什么问题?或者是否有其他方法来计算 price 列的总和?

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

谢谢!

I have a model:

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

I tried this to calculate the sum of price in this queryset:

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

What's wrong in this query? or is there any other way to calculate the Sum of price column?

I know this can be done by using for loop on queryset but i need an elegant solution.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

醉城メ夜风 2024-12-29 10:29:05

您可能正在寻找 聚合

from django.db.models import Sum

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

You're probably looking for aggregate

from django.db.models import Sum

ItemPrice.objects.aggregate(Sum('price'))
# returns {'price__sum': 1000} for example
薄凉少年不暖心 2024-12-29 10:29:05

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

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

Use .aggregate(Sum('column'))['column__sum'] reefer my example below

sum = Sale.objects.filter(type='Flour').aggregate(Sum('column'))['column__sum']
池予 2024-12-29 10:29:05

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

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

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

Aggregate 返回一个带有询问结果的字典:

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

Annotate adds a field to results:

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

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

Aggregate returns a dict with asked result:

>> Order.objects.aggregate(total_price=Sum('price'))
{'total_price': Decimal('1260.00')}
一抹淡然 2024-12-29 10:29:05

使用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总是需要更长的时间才能产生相同的结果。尽管我怀疑使用它而不是对列表求和可能在内存方面有优势。

Using cProfile profiler, I find that in my development environment, it is more efficient (faster) to sum the values of a list than to aggregate using Sum().
eg:

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.

I tested this in different contexts and it seems like using aggregate takes always longer to produce the same result. Although I suspect there might be advantages memory-wise to use it instead of summing a list.

软糯酥胸 2024-12-29 10:29:05

以前的答案非常好,而且,您可以通过一行普通代码得到总数......

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

Previous answers are pretty well, also, you may get that total with a line of vanilla code...

items = ItemPrice.objects.all()
total_price = sum(items.values_list('price', flat=True))
ι不睡觉的鱼゛ 2024-12-29 10:29:05

您还可以通过以下方式获取总和:

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

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

You could also get the sum this way:

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

Replace the 'amount' with the column name from your model you want to calculate the sum of and replace 'Sale' with your model name.

终止放荡 2024-12-29 10:29:05

您需要使用 聚合()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')}

You need to use aggregate() and Sum() to calculate the sum of price column as shown below. *The query with all() is equivalent to the query without all() as shown below:

from django.db.models import Sum

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

Then, these dictionaries below are outputted on console:

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

And, you can change the default key price__sum to priceSum for price column as shown below:

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

Then, the default key is changed as shown below:

{'priceSum': Decimal('150.00')}
{'priceSum': Decimal('150.00')}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文