我在djagno中有两个表
class Item(models.model):
name = models.TextField()
type = models.ForeignKey(ItemType)
quantity = models.IntegerField()
和
class ProductionRecord(models.model):
item = models.ForeignKey(Item)
done = models.IntegerField()
我想做的是将物品按类型分组,将所需物品的总数相加,然后对所生产物品的总数相加。
我相当接近,但我遇到的问题是,在执行.annotate(Sum("quantity"))
时,如果一个项目具有多个生产记录,它将根据每个记录再次对数量求和。
下面是连接表之后和分组之前我当前数据集的一个示例。
+--------+--------+--------------+----------------------+
| ItemId | TypeId | ItemQuantity | ProductionRecordDone |
+--------+--------+--------------+----------------------+
| 1257 | 7 | 4 | 1 |
| 1257 | 7 | 4 | 4 |
| 1259 | 7 | 4 | 4 |
| 1261 | 7 | 4 | 0 |
| 1263 | 7 | 4 | 4 |
| 1265 | 7 | 4 | 0 |
+--------+--------+--------------+----------------------+
在数量列上进行正常求和时,由于对项目id = 1257进行两次求和,因此返回24。
但是分组后我想返回的是:
+--------+--------------+------+
| TypeId | ItemQuantity | Done |
+--------+--------------+------+
| 7 | 20 | 13 |
+--------+--------------+------+
这是我当前的python代码供参考
Item.objects.values("type__name", "type__id") \
.annotate(total_done=Coalesce(Sum("productionrecord__done"), 0),
total_quantity=Coalesce(Sum("quantity",), 1))
是否有任何代码可用于仅对ItemId不同的行中的数量求和?
尝试:
queryset = Item.objects.values("type__name", "type__id") \
.filter(productionrecord__done=True) \
.annotate(total_done=Count("*"),
total_quantity=Sum("quantity"))
请不要显示queryset.query
,否则无法正常工作。
这无法在一个查询中完成,因为当与生产记录进行外部联接时,数量的总和将会复合。但是,您可以执行两个查询,然后合并字典:
data = {}
quantities = (
Item.objects.order_by("type_id")
.values("type_id")
.annotate(to_produce=Coalesce(Sum("quantity"), 1),)
)
for item in quantities:
type_id = item.pop("type_id")
data[type_id] = item
done = (
Item.objects.order_by("type_id")
.values("type_id")
.annotate(done=Coalesce(Sum("productionrecord__done"), 1),)
)
for item in done:
item_type_id = item.pop("type_id")
data[type_id].update(item)
for type_id, numbers in data.items():
print(type_id, numbers.get("to_produce"), numbers.get("done"))