Подтвердить что ты не робот

Django: вычисление суммы значений столбца посредством запроса

У меня есть модель

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

Я попробовал это, чтобы вычислить сумму price в этом наборе запросов:

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

что не так в этом запросе? или есть ли другой способ вычисления суммы столбца price?

Я знаю, что это можно сделать, используя for loop для набора запросов, но мне нужно элегантное решение.

Спасибо!

4b9b3361

Ответ 1

Вы, вероятно, ищете aggregate

from django.db.models import Sum

ItemPrice.objects.aggregate(Sum('price'))

Ответ 2

Annotate добавляет поле к результатам:

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

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

Агрегат возвращает dict с запрошенным результатом:

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

Ответ 3

Использовать агрегат (Sum ('column')) ['column__sum']

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

Ответ 4

Используя профилировщик 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 всегда приводит к более длительному результату для получения одинакового результата. Хотя я подозреваю, что может быть полезно использовать память вместо суммирования списка.

Ответ 5

Включается ли запрос ItemPrice.objects.aggregate(Sum ('price')) как часть поля в модели ItemPrice? Или этот запрос должен быть написан полностью отдельно от модели? Или эти наборы запросов выполняются только в views.py?