Django在自定义多对多模型上通过过滤器退出联接

时间:2019-05-16 13:14:00

标签: django django-models django-queryset django-orm

我有3个模型(用户默认模型,项目,ClickedUsers定制m2m模型),我想在ClickedUsers和Project模型的ORM中使用过滤器执行左连接。我在Stack Overflow上尝试了解决方案,但是当我打印这些查询时,我看到它们执行了内部联接。

这是我的模特:

class Project(models.Model):
        …
    clicked_users = models.ManyToManyField(User,through='ClickedUsers',blank=True)


class ClickedUsers(models.Model):
    user = models.ForeignKey(User,on_delete=models.CASCADE)
    project = models.ForeignKey(Project,on_delete=models.CASCADE)
    status = models.IntegerField(default=0)

以及我要执行的查询:

select * from project LEFT JOIN clickedusers ON project.id = clickedusers.project_id WHERE clickedusers.user_id = 1;

如何使用django orm完成此查询?

2 个答案:

答案 0 :(得分:2)

查看反向关系和related_name

Project.objects.filter(clicked_users__id=1)

或者您使用直通模型:

Project.objects.filter(clickedusers_set__user_id=1)

编辑: 我错过了select * from中的*。如果需要所有字段,则需要使用:

ClickedUser.objects.filter(
    user_id=1,
).select_related('project')

答案 1 :(得分:1)

在此查询中,LEFT JOININNER JOIN不会给您不同的结果

SELECT *
FROM table_1
JOIN table_2 on table_2.table_1_id = table_1.id
WHERE table_2.field = some_value;

由于在where子句中有table_2中的一个字段,因此只有在table_2中有记录时,才能从table_1中获取结果。 LEFT JOIN表示要从表_1获取记录,即使表_2中没有满足联接条件的记录。

未从所需的ORM处获取查询的原因是,ORM识别出它可以使用INNER JOIN而不是LEFT JOIN而不更改结果。