django left join + group by count(*),包括零计数

django left join + group by count(*), includes zero counts

class ItemGroup(models.Model):
   name = models.CharField(max_length=50)

class Item(models.Model):
   name = models.CharField(max_length=50)
   group = models.ForeignKey(ItemGroup, on_delete=models.CASCADE)

我想显示所有项目组,并为每个组显示该组具有的项目数,并包括没有项目的组。

在 SQL 中,我为此使用左连接:

SELECT item_group.name, COUNT(*) as item_count
FROM item_group
LEFT JOIN item ON item_group.id = item.id
GROUP BY item_group.id, item_group.name

所以我也得到了计数为零的组。

如何用django ORM做等价的查询?

您需要使用 django 注释。稍微修改您的外键为:

group = models.ForeignKey(ItemGroup, related_name='items', on_delete=models.CASCADE)

方便命名。

然后 运行 python manage.py makemigration 接着是 python manage.py migrate

接下来是注释时间

from django.db.models import Count
ItemGroup.objects.annotate(no_of_items=Count('items'))

这样做是为每个 ItemGroup 对象添加一个名为 no_of_items 的属性,该属性是与其相关的 items 的计数。

现在,如果您 item_group = ItemGroup.objects.get(id=1) 假设项目组 1 有 3 个相关项目,您可以 item_group.no_of_items 得到 3 个。如果另一个 ItemGroup 有 0 个项目,它会 return 零。

有关注释的更多信息,请参阅 https://docs.djangoproject.com/en/2.1/topics/db/aggregation/