Django аннотирует несколько агрегаторов над сгруппированными значениями
В связи со структурой моего проекта, мне необходимо иметь несколько агрегаций над тремя взаимосвязанными таблицами. Структура выглядит примерно так:
class ItemMeta(models.Model):
item = models.ForeignKey(
Item, on_delete=models.SET_NULL, null=True
)
class = models.CharField(max_length=2048, null=True, blank=True)
department = models.CharField(max_length=2048, null=True, blank=True)
class Item(models.Model):
amount = models.DecimalField(max_digits=18, decimal_places=2)
status = models.CharField(max_length=2048, null=True, blank=True, choices=ItemStatus.choices)
class CartItem(models.Model):
author = models.ForeignKey(to=UserModel, on_delete=model.CASCADE)
item = models.ForeignKey(Item, on_delete=models.CASCADE)
class ItemStatus(models.TextChoices):
UNDER_CONSIDERATION = 'UNDER_CONSIDERATION', 'Under consideration'
IMPOSED = 'IMPOSED', 'Imposed'
PAID = 'PAID', 'Paid'
А мне нужно иметь группировку товаров по классу, отделу и статусу как в корзине, так и вне ее. Мне также нужно иметь агрегаты суммарных сумм товаров в разных статусах, а также подсчеты количества разных товаров в корзине и существующих. Таким образом, структура ответа должна всегда содержать 5 значений: сумму оплаченных, наложенных и рассматриваемых товаров, а также количество товаров, существующих и находящихся в корзине вызывающего пользователя. Я унаследовал от прошлого бедолаги этот кусок кода, чтобы сделать это:
def _sum(self, status):
return Coalesce(Sum('amount', filter=Q(status=status)), 0.0, output_field=FloatField())
def annotate_kwargs(self):
return {
'under_consideration_amount': self._sum(ItemStatus.UNDER_CONSIDERATION),
'imposed_amount': self._sum(ItemStatus.IMPOSED),
'paid_amount': self._sum(ItemStatus.PAID),
'count': Count('pk', distinct=True),
'in_cart': Count('pk', distinct=True, filter=Q(cartitem__author=self.user)),
}
def get(self):
return self.queryset \
.values(*self.group_by) \
.annotate(**self.annotate_kwargs())
Который в основном берет набор запросов Item и группирует их в соответствии с запросом, а затем аннотирует их. Проблема в том, что она возвращает ложь, как показано в docs. Возможно, наличие 3 разных таблиц как-то связано с этим, но на данный момент у меня нет возможности изменить структуру модели, поэтому она должна оставаться такой, какая есть, или иметь как можно меньше изменений. Мой вопрос в том, как получить эти агрегаты? Я пытался использовать подзапрос, но я не знаю, как заставить его работать с клаузулой .values