Django查询外键计数()零
我有三张桌子: 卡车带有以下字段:Django查询外键计数()零,django,django-queryset,Django,Django Queryset,我有三张桌子: 卡车带有以下字段:id,name 菜单包含以下字段:id,itemname,id\u foodtype,id\u truck Foodtype带有以下字段:id,type 我想得到如下总结: id name total 10 Alcoholic drink 0 5 Appetizer 11 我的问题是返回带有0元素的结果 我尝试了如下SQL查询: SELECT ft.id, ft.name, COUNT(me.id)
id
,name
菜单包含以下字段:id
,itemname
,id\u foodtype
,id\u truck
Foodtype带有以下字段:id
,type
我想得到如下总结:
id name total
10 Alcoholic drink 0
5 Appetizer 11
我的问题是返回带有0
元素的结果
我尝试了如下SQL查询:
SELECT
ft.id, ft.name, COUNT(me.id) total
FROM
foodtype ft LEFT JOIN menu me
ON ft.id = me.id_foodtype
LEFT JOIN truck tr
ON tr.id = me.id_truck AND tr.id = 3
GROUP BY ft.id, ft.name
ORDER BY ft.name
或Django中的查询
Menu.objects.filter(id_truck=3).values("id_foodtype").annotate(cnt=Count("id_foodtype"))
但是,这两种方法都没有使用零
元素显示结果
在将此查询转换为Python时,我的任何查询都会返回我期望的准确结果。
如何使用
左连接返回结果,包括菜单中零元素的食物类型
?左连接的方向取决于启动查询的对象。如果从菜单启动
,您将永远不会看到所选菜单项未使用的食物类型
。然后,重要的是(在您的情况下,通过卡车)进行过滤,允许使用null value Menu.id以获得Count==0
from django.db.models import Q
qs = (
FoodType.objects
.filter(Q(menu_set__id_truck=3) | Q(menu_set__id__isnull=True))
.values() # not necessary, but useful if you want a dict, not a Model object
.annotate(cnt=models.Count("menu_set__id"))
)
验证:
>>> print(str(qs.query))
SELECT foodtype.id, foodtype..., COUNT(menu.id) AS cnt
FROM foodtype
LEFT OUTER JOIN menu ON (foodtype.id = menu.id_foodtype)
WHERE _menu.id_truck = 3 OR menu.id IS NULL)
GROUP BY foodtype.id
它适用于当前最新和最旧的Django 2.0b1和1.8
无论是否有行.values()
,查询都是相同的。结果是具有cnt
属性的字典或FoodType对象
脚注:
如果定义了相关名称,则名称菜单集
应替换为外键id\u foodtype
的真实相关名称
class Menu(models.Model):
id_foodtype = models.ForeignKey('FoodType', on_delete=models.DO_NOTHING,
db_column='id_foodtype', related_name='menu_set'))
...
如果启动一个新项目,我建议将外键重命名为不带“id”的名称,并且db_列字段带“id”。然后menu\u item.foodtype
是一个食物对象,而menu\u item.id\u foodtype
itsid
这更像是一个sql postgres的问题,而不是djangoI编辑了您的问题,以便于搜索,希望它是可以接受的。我也编辑了我的答案。