在 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 的回答表明的关系。
我有一个模型:
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 的回答表明的关系。