Джанго Аннотат Сум - PullRequest
0 голосов
/ 09 мая 2018

Я пытаюсь получить простую сумму для столбца с несколькими строками в наборе запросов. Мой прямой вопрос (а) как мне установить get_queryset(), чтобы включить сумму столбца и (б) как я могу получить доступ к этому элементу в шаблоне? Следующий этот вопрос:

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

Предусмотрено два ответа - один с использованием метода .aggregate(), который, как мне кажется, не возвращает набор запросов, и метод .annotate(), который, как мне кажется, добавляет элемент в набор запросов.

Итак, я ожидал, что следующее добавит еще один элемент в список объектов в этом представлении:

#views.py
def get_queryset(self):
    # generate table and filter down to a subquery.
    queryset = ItemPrice.objects.filter(<some_filter>)
    # sum the price for each row in the subquery.
    queryset = queryset.annotate(totals=Sum('price'))
    return queryset

Тогда в Шаблоне я мог бы перебирать список объектов следующим образом:

#template.html
{% for item in object_list %}
    {{ item }}
{% endfor %}

С ожиданием, что один из пунктов (последний элемент?) Будет price_sum и что баланс может быть получен как price_sum.price.

Однако, когда я добавляю следующее в свой шаблон, я получаю цены для каждой позиции - без суммирования.

{% for item in object_list %}
    {{ item.totals }}
{% endfor %}

Но я не могу получить доступ к предмету. Я не знаю, если проблема заключается в изменении вида get_queryset() или в шаблоне?

Ответы [ 2 ]

0 голосов
/ 10 мая 2018

, если вы хотите добавить данные в шаблон

queryset = ItemPrice.objects.filter(<your_filter>)
totals = queryset.aggregate(sum=Sum('price').get('sum')

context  = {
    'object_list': queryset,
    'totals: totals,
}
render(request, '<name_of_your_template>.html', context)

и в вашем шаблоне

{% for item in object_list %}
    # price of item
    {{ item.price }}
{% endfor %}
# total price
{{ totals }}
0 голосов
/ 09 мая 2018

, если вы используете:

ItemPrice.objects.filter(<some_filter>).annotate(totals=Sum('price'))

итоги всегда будут такими же, как 'цена'

аннотировать (о сумме) использует как это:

если у вас есть эти модели:

class ItemPrice( models.Model ):
    price = models.DecimalField ( max_digits = 8, decimal_places=2 )
    other_model = models.ForeignKey(
          to=OtherModel, 
          related_name="item_prices", 
          on_delete=models.SET_NULL
    )

# related_name - if I set related_name I can use like this
# other_model_object.item_prices.all() - this code return all 
# ItemPrices with other_model_id=other_model_object.id

class OtherModel(models.Model):
    some_field = models.CharField(max_lenght=256)

и вы хотите, чтобы во всех ценах всех ItemPrices, которые имеют внешний ключ к одной OtherModel, вы должны использовать этот код:

queryset = OtherModel.objects.annotate(
       total_prices=Sum('item_prices__price')
).filter(<your_filters>)

после этого вы можете использовать:

for obj in queryset:
    print(obj.total_prices)

Или, если вам нужна сумма всех цен, вы должны использовать агрегат

ItemPrices.objects.aggregate(all_sum=Sum('price'))

этот код возвращает dict (или что-то подобное, я точно не помню) как это

{'all_sum': 1250}

all_sum - сумма всех объектов в вашей таблице в базе данных

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...