我想知道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')
答案 0 :(得分:1)
您当然可以,但是据我所知,您不能使用aggregate()
。尝试在aggregate()
中使用Subquery
时,django抱怨试图执行具有OuterRef
的查询。我这样做的方式(我真的不知道这是否是- 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
我没有运行该示例,因此可能需要在此处和此处进行一些调整。