在 django 中使用注释并计算框中的部分数

Using annotate in django and counting number of sections in a box

我有一个模型:

class ShipmentItem(models.Model):
    shipment_box = models.IntegerField(null=True, blank=True)
    section = models.CharField(
        max_length=15,
        choices=[(1, "A"), (2, "B"), (3, "C"), (4, "D")],
        null=True,
        blank=True,
        default=1,
    )

我正在编写关于 ShipmentItem 模型的查询...

self.queryset.annotate(
    quantity=Count("section", filter=Q(shipment_box=F("shipment_box")))
).order_by("shipment_box", "section")

出于某种原因,数量不变返回为 1 无论我是否知道还有更多要量化

如何让注释工作?

annotate 适用于相关模型,您的模型中没有任何关系。

我不知道你的具体情况,但我认为你应该重新考虑构建/设置模型的方式。

像这样为您的场景想象修改后的模型:

class ShipmentSection(models.Model):
    section = models.CharField(max_length=15, choices=[(1, 'A'), (2, 'B'), (3, 'C'), (4, 'D')], null=True, blank=True, default=1)

class ShipmentItem2(models.Model):
    shipment_box = models.IntegerField(null=True, blank=True)
    section = models.ManyToManyField(ShipmentSection)

现在,如果我执行以下操作:

>>> item = ShipmentItem2(shipment_box=1)
>>> item.save()
>>> section_1 = ShipmentSection(section=1)
>>> section_1.save()
>>> section_2 = ShipmentSection(section=2)
>>> section_2.save()
>>> item.section.add(section_1)
>>> item.section.add(section_2)
>>> item.save()
>>> ShipmentItem2.objects.all().annotate(quantity=Count(F('section')))[0].quantity
2
>>> item.section.count()
2

正如您通过 ManyToManyField 看到的那样,通过在集合本身上使用快捷方式 count() 方法可以更轻松地进行计数。

根据您目前的设计,我认为您正在寻找的是使用 Window 函数:

ShipmentItem.objects.annotate(
    quantity=models.Window(
        expression=models.Count('section'),
        partition_by=[models.F('section')],
    ),
).order_by("shipment_box", "section")

不过请记住,您当前的设计只允许每个 ShipmentItem 有一个部分,因此如果您需要允许一个项目有多个部分,则必须切换到 ManyToMany @yvesonline 的回答表明的关系。