Django - показывать суммы таблицы рекордов - PullRequest
3 голосов
/ 18 сентября 2011

У меня есть таблица со списком счетов и их реквизитами:

class Invoice(models.Model):
    invoiceNum = models.CharField(etc...)
    invoiceDate = models.DateField(etc...)
    customerID = models.ForeignKey(etc...)
    isPaid = models.CharField(etc...)

Записи Invoice не содержат фактическую сумму счета. Вместо этого сумма счета-фактуры состоит из нескольких записей Invoice_Line_Item, которые хранятся в другой таблице:

class Invoice_Line_Item(models.Model):
    invNum = models.ForeignKey(Invoice)
    itemName = models.CharField(etc...)
    itemPrice = models.DecimalField(etc...)

У меня есть веб-приложение, которое показывает все счета в большой таблице HTML, а также все детали этого счета в строке tr таблицы. Такие данные, как дата выставления счета, номер счета, идентификатор клиента, все взяты из этой таблицы Invoice. В этом HTML table.

отображаются сотни счетов.

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

Один из способов, который я подумал - передать весь набор запросов Invoice_Line_Item в шаблон HTML, а затем для каждого счета-фактуры, отображаемого в таблице tr, я мог бы выполнить итерацию всего набора запросов Invoice_Line_Item, суммируя все позиции которые соответствуют текущему счету. Это, однако, кажется чрезвычайно неэффективным.

Есть лучшие идеи, как это сделать?

Спасибо!

Ответы [ 2 ]

4 голосов
/ 18 сентября 2011

Одно слово: агрегация

Invoice_Line_Item.objects.filter(invNum=invoice).aggregate(Sum('itemPrice'))

https://docs.djangoproject.com/en/dev/topics/db/aggregation/

Другой способ - сохранить итоговую сумму в счете-фактуре и обновлять ее всякий раз, когда вы изменяете связанную Invoice_Line_Item

0 голосов
/ 10 декабря 2011

Еще одно слово: аннотировать.

from django.models import Sum

Invoice.objects.filter( .. ).annotate( InvTotal=Sum( 'invoice_line_number__itemPrice' ) ) 

InvTolal становится новым атрибутом объекта Invoice, его можно использовать в шаблоне так же, как invoiceNum или invoiceDate.

При таком подходе вам не нужно передавать какие-либо дополнительные структуры данных в шаблон, только QuerySet of Invoices.

Обратите внимание: Аргумент Sum - это строка, представляющая собой конкатенацию имени связанной модели, преобразованного в нижний регистр, чем двойное «_», и имени поля в связанной модели.

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