如何注释Django QuerySet聚合带注释的子查询

时间:2019-03-12 19:25:28

标签: python django aggregate django-orm annotate

我有一些具有FK关系的Django模型:

from django.db import models


class Order(models.Model):
    notes = models.TextField(blank=True, null=True)


class OrderLine(models.Model):
    order = models.ForeignKey(Order, on_delete=models.CASCADE)
    quantity = models.PositiveIntegerField()
    price = models.DecimalField(max_digits=8, blank=True, decimal_places=2)

给定OrderLine,您可以按价格将其总数计算为数量:

def get_order_line_total(order_line):
    return order_line.quantity * order_line.price

给出订单,您可以将其总数计算为订单行总数之和:

def get_order_total(order):
    order_total = 0
    for orderline_for in order.orderline_set.all():
        order_total += (order_line_for.quantity * order_line_for.price)
    return order_total

我想注释查询集中的总数,以便可以过滤它们,对其进行排序等。

对于OrderLine模型,我发现它非常简单:

from django.db.models import F, FloatField, Sum


annotated_orderline_set = OrderLine.objects.annotate(orderline_total=Sum(F('quantity') * F('price'), output_field=FloatField()))

现在,我要在Order.objects查询集中注释总数。我想我需要使用子查询,但是我无法使其工作。 我的猜测是(无效):

from django.db.models import F, FloatField, OuterRef, Subquery, Sum


Order.objects.annotate(
    order_total=Subquery(
        OrderLine.objects.filter(
            order=OuterRef('pk')
        ).annotate(
            orderline_total=Sum(F('quantity') * F('price'), output_field=FloatField())
        ).values(
            'orderline_total'
        ).aggregate(
            Sum('orderline_total')
        )['orderline_total__sum']
    )
)

# Not working, returns:
# ValueError: This queryset contains a reference to an outer query and may only be used in a subquery.

我该如何解决?

0 个答案:

没有答案