Saya punya model
class ItemPrice( models.Model ):
price = models.DecimalField ( max_digits = 8, decimal_places=2 )
....
Saya mencoba ini untuk menghitung jumlah price
dalam queryset ini:
items = ItemPrice.objects.all().annotate(Sum('price'))
apa yang salah dalam pertanyaan ini? atau adakah cara lain untuk menghitung Jumlah price
kolom?
Saya tahu ini dapat dilakukan dengan menggunakan for loop di queryset tetapi saya membutuhkan solusi yang elegan.
Terima kasih!
Jawaban:
Anda mungkin sedang mencari
aggregate
from django.db.models import Sum ItemPrice.objects.aggregate(Sum('price')) # returns {'price__sum': 1000} for example
sumber
{'price__sum':1000}
. Bisa mendapatkan float / integer denganyourdict['price__sum']
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')}
sumber
key
untuk menyimpan jumlah tersebutvalue
.Gunakan
.aggregate(Sum('column'))['column__sum']
reefer contoh saya di bawah inisum = Sale.objects.filter(type='Flour').aggregate(Sum('column'))['column__sum']
sumber
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
aggregate
selalu lebih lama untuk menghasilkan hasil yang sama. Meskipun saya curiga mungkin ada keuntungan dari segi memori untuk menggunakannya daripada menjumlahkan daftar.sumber
sum_a = sum(item.column for item in queryset)
. Satu-satunya perbedaan adalah[]
s dihapus . Ini menghemat ruang memori untuk menghitung seluruh daftar sebelumsum()
mengulanginya.