Django: Hitung Jumlah nilai kolom melalui query


93

Saya punya model

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

Saya mencoba ini untuk menghitung jumlah pricedalam queryset ini:

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

apa yang salah dalam pertanyaan ini? atau adakah cara lain untuk menghitung Jumlah pricekolom?

Saya tahu ini dapat dilakukan dengan menggunakan for loop di queryset tetapi saya membutuhkan solusi yang elegan.

Terima kasih!


Apakah ini menjawab pertanyaan Anda? Pertanyaan Django SUM?
Flimm

Jawaban:


197

Anda mungkin sedang mencari aggregate

from django.db.models import Sum

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

1
Bagaimana saya bisa menghitung total yang harganya = 5000?
Anuj Sharma

6
Ingat mengembalikan kamus bukan float / integer misalnya {'price__sum':1000}. Bisa mendapatkan float / integer denganyourdict['price__sum']
Josh

35

Anotasi menambahkan bidang ke hasil:

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

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

Agregat mengembalikan sebuah dict dengan hasil yang diminta:

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

Saya menghargai Anda menunjukkan bagaimana menentukan keyuntuk menyimpan jumlah tersebut value.
MikeyE

32

Gunakan .aggregate(Sum('column'))['column__sum']reefer contoh saya di bawah ini

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

5

Dengan menggunakan cProfile profiler , saya menemukan bahwa dalam lingkungan pengembangan saya, lebih efisien (lebih cepat) untuk menjumlahkan nilai-nilai daftar daripada menggunakan agregat Sum(). misalnya:

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.

Saya menguji ini dalam konteks yang berbeda dan sepertinya menggunakan aggregateselalu lebih lama untuk menghasilkan hasil yang sama. Meskipun saya curiga mungkin ada keuntungan dari segi memori untuk menggunakannya daripada menjumlahkan daftar.


1
Atau, menggunakan ekspresi pembangkit bukannya daftar: sum_a = sum(item.column for item in queryset). Satu-satunya perbedaan adalah []s dihapus . Ini menghemat ruang memori untuk menghitung seluruh daftar sebelum sum()mengulanginya.
Code-Apprentice
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.