我们可以使用 Django 子查询进行算术运算吗?

Can we do arithmetic using Django Subqueries?

我想知道 Django 的 ORM 是否允许我们对子查询进行聚合操作,然后对结果值进行算术运算。

处理这样的事情的正确方法是什么:

record = PackingRecord.objects.filter(product=OuterRef('pk'))
packed = FifoLink.objects.filter(packing_record__product=OuterRef('pk'))

output = obj_set.annotate(
    in_stock=(Subquery(record.aggregate(Sum('qty'))) - Subquery(packed.aggregate(Sum('sale__qty'))))
).values('id', 'name', 'in_stock')

你当然可以,但据我所知,你不能使用aggregate()。当尝试在 Subquery 中使用 aggregate() 时,django 抱怨试图执行具有 OuterRefs 的查询。我这样做的方式(我真的不知道这是不是 - according to the docs it is - 的方式)是使用 annotate()。对于您示例中的情况,我会执行以下操作:

records_total = (PackingRecord.objects.filter(product=OuterRef('pk'))
    .values('product') # Group by product
    .annotate(total=Sum('qty')) # Sum qty for 'each' product
    .values('total')
)
packed_total = (FifoLink.objects.filter(packing_record__product=OuterRef('pk'))
    .values('packing_record__product') # Group by packing_record__product
    .annotate(total=Sum('sale__qty')) # Sum sale__qty for 'each' product
    .values('total')
)
output = obj_set.annotate(
    r_tot=Subquery(record_total[:1]),
    p_tot=Subquery(packed_total[:1])
).annotate(
    in_stock=F('r_tot')-F('p_tot')
) # Whatever you need

我没有运行这个例子,所以这里和那里可能需要一些调整。