У меня есть модель
class ItemPrice( models.Model ):
price = models.DecimalField ( max_digits = 8, decimal_places=2 )
....
Я пробовал это, чтобы вычислить сумму price
в этом наборе запросов:
items = ItemPrice.objects.all().annotate(Sum('price'))
что не так в этом запросе? или есть ли другой способ вычислить сумму price
столбца?
Я знаю, что это можно сделать, используя цикл for в наборе запросов, но мне нужно элегантное решение.
Благодарность!
Ответы:
Вы, наверное, ищете
aggregate
from django.db.models import Sum ItemPrice.objects.aggregate(Sum('price')) # returns {'price__sum': 1000} for example
источник
{'price__sum':1000}
. Можно получить числа с плавающей точкой или целое число с помощьюyourdict['price__sum']
Аннотации добавляет поле к результатам:
>> Order.objects.annotate(total_price=Sum('price')) <QuerySet [<Order: L-555>, <Order: L-222>]> >> orders.first().total_price Decimal('340.00')
Агрегат возвращает запрос с запрошенным результатом:
>> Order.objects.aggregate(total_price=Sum('price')) {'total_price': Decimal('1260.00')}
источник
key
следует хранить суммуvalue
.Используйте
.aggregate(Sum('column'))['column__sum']
мой пример нижеsum = Sale.objects.filter(type='Flour').aggregate(Sum('column'))['column__sum']
источник
Используя профилировщик 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
всегда занимает больше времени для получения того же результата. Хотя я подозреваю, что использование его вместо суммирования списка может иметь преимущества с точки зрения памяти.источник
sum_a = sum(item.column for item in queryset)
. Единственное отличие - удаленные[]
s. Это экономит место в памяти для вычисления всего списка перед егоsum()
итерацией.