Django:クエリを使用して列の値の合計を計算します


98

私はモデルを持っています

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

priceこのクエリセットの合計を計算するためにこれを試しました:

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

このクエリの何が問題になっていますか?または、price列の合計を計算する他の方法はありますか?

これはクエリセットでforループを使用して実行できることはわかっていますが、洗練されたソリューションが必要です。

ありがとう!


これはあなたの質問に答えますか?Django SUMクエリ?
Flimm

回答:


202

あなたはおそらく探しています aggregate

from django.db.models import Sum

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

1
価格= 5000の合計カウントを取得するにはどうすればよいですか?
アヌジシャルマ2018

6
float / integerではなく辞書を返すことを忘れないでください{'price__sum':1000}。フロート/整数を得ることができますyourdict['price__sum']
ジョシュ・

37

Annotateは、結果にフィールドを追加します。

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

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

Aggregateは、要求された結果でdictを返します。

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

key合計を格納するを指定する方法を示していただきありがとうございますvalue
MikeyE

35

.aggregate(Sum('column'))['column__sum']以下の私の例を冷凍して使用してください

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

エラーが発生します: 'decimal.Decimal'オブジェクトは反復できません
Roni X

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、同じ結果を生成するには、使用すると常に時間がかかるようです。リストを合計する代わりにそれを使用することはメモリ的に利点があるかもしれないと私は思うが。


3
または、リストの代わりにジェネレータ式を使用しますsum_a = sum(item.column for item in queryset)。唯一の違いは、削除された[]sです。これにより、リストをsum()反復処理する前にリスト全体を計算するためのメモリスペースが節約されます。
コード-見習い

エラーが発生する: 'decimal.Decimal'オブジェクトは反復できません
Roni X
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.