Django ORM query with multiple joins

时间:2016-08-31 17:31:45

标签: python mysql django join orm

I've been trying to come up with the django version of this query and I can't seem to get it.

SELECT
  *
FROM answer a
LEFT JOIN groups g
  ON a.group_id = g.id
LEFT JOIN group_permissions gp
  ON g.id = gp.group_id
WHERE gp.user_id = '77777';

I've been trying something like this:

answers = Answer.objects.filter(user_id=user_id).prefetch_related('group__grouppermissions')

Answers are associated to groups. Groups are associated to multiple users. Group permissions are associated to groups and users.

I'm sure I'm missing some relationship somewhere.

Models:

class User(models.Model):
    id = models.BigAutoField(primary_key=True)
    username = models.CharField(max_length=255)

class Answer(models.Model):
    id = models.BigAutoField(primary_key=True)
    user = models.ForeignKey('User', models.DO_NOTHING)
    group = models.ForeignKey('Groups', models.DO_NOTHING)
    class Meta:
        managed = False
        db_table = 'answer'

class Groups(models.Model):
    id = models.BigAutoField(primary_key=True)
    name = models.CharField(unique=True, max_length=255)

    class Meta:
        managed = False
        db_table = 'groups'

class GroupPermissions(models.Model):
    id = models.BigAutoField(primary_key=True)
    group = models.ForeignKey('Groups', models.DO_NOTHING)
    user = models.ForeignKey('User', models.DO_NOTHING)
    role = models.IntegerField()

    class Meta:
        managed = False
        db_table = 'group_permissions'

1 个答案:

答案 0 :(得分:0)

django为您创建了一个隐式关联:group_grouppermissions_set。您可以在docs中了解多对一关系。

所以你的查询看起来像这样:

answers = Answer.objects.\
    filter(group__grouppermissions_set__user_id=77777)

另请注意,django将创建LEFT OUTER JOIN

然后,当您确信您的查询有效时,您可以使用类似的查找向prefetch_related添加优化。这取决于您希望从Answer模型获取的深度。