在Django中使用远程外键关系查询sum

kx1ctssn  于 2023-10-21  发布在  Go
关注(0)|答案(1)|浏览(179)

假设我有这样的模型:

class Product(models.Model):
    ...

class Item(models.Model):
    product = models.ForeignKey(Product, related_name="items")
    quantity = models.IntegerField()

class Order(models.Model):
    item = models.ForeignKey(Item, related_name="orders")
    quantity = models.IntegerField()

我现在想得到一个Product的列表,它用字段total_supply进行注解。每种产品的“总供应量”定义如下:(所有产品项的总和quantity)-(与产品项之一关联的所有Order对象的总和quantity)。
以下是我尝试过的:
Product.objects.annotate(actual_supply=Sum("items__quantity") - Sum("items__orders__quantity"))
我得到了意想不到的结果。我该怎么写这样的查询呢?
谢谢你

iq0todco

iq0todco1#

问题是你在这里做了 * 2 * JOIN s,这意味着对于每个Order,它将添加itemquantity,所以相同的数量被添加多次。
因此,这意味着如果你有一个Itemquantity=5,以及两个quantity=1quantity=2的订单,人们会期望结果是2,但是因为Item被求和两次,结果将是7
可以在这里使用子查询来避免这种效果,比如:

from django.db.models import OuterRef, Subquery

Product.objects.annotate(
    actual_supply=Subquery(
        Item.objects.filter(
            product_id=OuterRef('pk')
            .values('product_id')
            .values(a=Sum('quantity'))
            .order_by('product_id')[:1]
        )
    )
    - Sum('items__orders__quantity')
)

相关问题