Получить QuerySet с GROUP BY с полными связанными экземплярами модели вместо dict - PullRequest
0 голосов
/ 06 ноября 2018

У меня есть 3 (упрощенные для этого предложения) модели:

TaxRate(models.Model):
    rate = models.DecimalField()
    name = models.CharField()

    @property 
    def friendly_name(self):
         return some_string

InvoiceLine(models.Model):
    invoice = models.ForeignKey('Invoice', related_name="lines")
    netto = models.DecimalField()
    rate = models.ForeignKey('TaxRate')

Invoice(models.Model):
    no = models.CharField()

Я пытаюсь получить строки счета-фактуры, сгруппированные по taxrate__rate. Я делаю

invoice.lines.order_by('-taxrate__rate').values('taxrate__rate')\
    .annotate(
        sum_netto=models.Sum('netto')
    )

и я получаю список диктов с таким

[{'taxrate__rate': Decimal(7.00), 'sum_netto': Decimal(12.00)}]'

это нормально, но я хотел бы получить тот же результат с объектом TaxRate, где я могу использовать метод friendly_name.

Есть ли способ сделать это, используя только один простой (как этот) запрос? Я знаю, что не могу использовать .only() .defer(), потому что тогда он не сгруппирован по taxrate__rate, потому что поле id обязательно для этого.

Я также не хочу делать это на стороне Python (например, цикл for для различных таксатов и затем агрегировать sum_netto или просто создавать список dicts в python из набора запросов)

мое временное решение (это ужасно, я знаю), когда self - это счет:

    lines = self.lines.order_by('-taxrate__rate')\
        .values('taxrate__rate', 'taxrate')\
        .annotate(
            sum_netto=models.Sum('netto'),
        )
    for idx, line in enumerate(lines):
        lines[idx]['taxrate'] = TaxRate.objects.get(id=line['taxrate'])

    return lines

Мое второе (и, на самом деле, лучшее на данный момент) решение (когда «Я» выставляет счет):

return TaxRate.objects\
    .filter(invoiceline__invoice=self).distinct()\
    annotate(
        sum_netto=models.Sum('invoiceline__netto')
    )

но все же это не очень идиоматично и как-то нелогично

есть ли лучший способ?

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