Django: Sorgu yoluyla sütun değerlerinin toplamını hesaplayın


92

Bir modelim var

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

priceBu sorgu kümesindeki toplamını hesaplamak için bunu denedim :

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

bu sorguda yanlış olan ne? veya priceSütun Toplamını hesaplamanın başka bir yolu var mı?

Bunun sorgu kümesi üzerinde for döngüsü kullanılarak yapılabileceğini biliyorum, ancak zarif bir çözüme ihtiyacım var.

Teşekkürler!


Bu sorunuzu yanıtlıyor mu? Django SUM Sorgusu?
Flimm

Yanıtlar:


196

Muhtemelen arıyorsun aggregate

from django.db.models import Sum

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

1
Fiyatı 5000 olan toplam sayımı nasıl alabilirim?
Anuj Sharma

6
Döndürür sözlüğü unutmayın float / integer değil örn {'price__sum':1000}. yourdict['price__sum']
Josh

35

Ek açıklama, sonuçlara bir alan ekler:

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

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

Aggregate, istenen sonucu içeren bir dict döndürür:

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

Toplamın keysaklanacağını nasıl belirteceğinizi gösterdiğiniz için teşekkür ederim value.
MikeyE

32

.aggregate(Sum('column'))['column__sum']Aşağıdaki örneğimde reefer kullanın

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

5

CProfile profil oluşturucuyu kullanarak, geliştirme ortamımda , bir listenin değerlerini toplamanın kullanmaktan daha verimli (daha hızlı) olduğunu buldum Sum(). Örneğin:

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.

Bunu farklı bağlamlarda test ettim aggregateve aynı sonucu üretmek için kullanmak her zaman daha uzun sürüyor gibi görünüyor . Bir listeyi toplamak yerine kullanmanın hafıza açısından avantajları olabileceğinden şüphelenmeme rağmen.


1
Alternatif olarak, yerine listenin bir jeneratör ifade kullanın: sum_a = sum(item.column for item in queryset). Tek fark, kaldırılan []e-postalardır. Bu, sum()üzerinde yinelemeden önce tüm listenin hesaplanması için bellek alanından tasarruf sağlar .
Code-Apprentice
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.