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

时间:2019-02-25 17:34:30

标签: python django django-models django-orm

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进行等效查询?

1 个答案:

答案 0 :(得分:1)

您需要使用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的计数。

现在,如果您假设项目组1有3个与之相关的项目进行item_group = ItemGroup.objects.get(id=1),则可以执行item_group.no_of_items,这将给您3。如果另一个ItemGroup有0个项目,它将返回零。

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