Can we do arithmetic using Django Subqueries?

本小妞迷上赌 提交于 2019-12-13 20:18:46

问题


I am wondering if Django's ORM allows us to do aggregate operations on subqueires, and then do arithmetic with the resulting values.

What would be the proper way to go about something like this:

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')

回答1:


You certainly can but as far as I have dig, you cannot use aggregate(). When trying to use aggregate() in a Subquery django complains about trying to execute a query that has OuterRefs. The way I do this (I really don't know if this is THE way - according to the docs it is -) is by using annotate(). In a case like the one you have in your example I'd do something like the following:

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

I did not run the example, so it may need some adjustments here and there.



来源:https://stackoverflow.com/questions/53892193/can-we-do-arithmetic-using-django-subqueries

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!