Возможны ли вложенные агрегированные запросы в Django queryset

Я хочу рассчитать ежемесячную прибыль на основе следующих моделей, используя django queryset methods.
Сложный момент заключается в том, что у меня есть поле freightselloverride в таблице заказов. Оно переопределяет сумму freightsell в таблице orderItem. Вот почему я должен сначала рассчитать прибыль на основе заказа, а затем рассчитать прибыль на основе месяца. Потому что если есть данные freightselloverride на уровне заказа, я должен принять это во внимание.

Ниже я попробовал использовать метод annotate, но не смог решить, как достичь этого SQL. Позволяет ли Django такой вид вложенных агрегированных запросов?


select sales_month
    ,sum(sumSellPrice-sumNetPrice-sumFreighNet+coalesce(FreightSellOverride,sumFreightSell)) as profit
from
    (
    select CAST(DATE_FORMAT(b.CreateDate, '%Y-%m-01 00:00:00') AS DATETIME) AS `sales_month`,
        a.order_id,b.FreightSellOverride
        ,sum(SellPrice) as sumSellPrice,sum(NetPrice) as sumNetPrice
        ,sum(FreightNet) as sumFreighNet,sum(FreightSell) as sumFreightSell
    from OrderItem a
    inner join Order b
    on a.order_id=b.id
    group by 1,2,3
    ) c
group by sales_month


from django.db import models
from django.db.models import F, Count, Sum
from django.db.models.functions import TruncMonth

class Order(models.Model):
    CreateDate = models.DateTimeField(verbose_name="Create Date")
    FreightSellOverride = models.FloatField()

class OrderItem(models.Model):
    SellPrice = models.DecimalField(max_digits=10,decimal_places=2)
    FreightSell = models.DecimalField(max_digits=10,decimal_places=2)
    NetPrice = models.DecimalField(max_digits=10,decimal_places=2)
    FreightNet = models.DecimalField(max_digits=10,decimal_places=2)
    order = models.ForeignKey(Order,on_delete=models.DO_NOTHING,related_name="Item")


result = (OrderItem.objects
        .annotate(sales_month=TruncMonth('order__CreateDate'))
        .values('sales_month','order','order__FreightSellOverride')
        .annotate(profit=Sum(F('SellPrice')-F('NetPrice')-F('FreightNet')),freight=Sum('FreightSell'))
        )

Вернуться на верх