强制django使用两个外键中的一个

时间:2015-04-03 18:27:43

标签: django django-queryset

我有一个带有两个外键的模型。 数据库结构:

class LightUsers(models.Model):
    admin = models.ForeignKey(User, db_index=True, related_name="lightuser_admin")
    user = models.ForeignKey(User, db_index=True, related_name="lightuser_user")

class User(models.Model):
    ...

我想执行以下查询:

SELECT * FROM lightusers INNER JOIN user ON (lightusers.admin_id = user.id) WHERE lightusers.user_id IN ( 1, 2, 3)

为实现这一目标,我写了下一段代码:

light_users = LightUsers.objects.filter(user__in=[1,2,3]).select_related('user')

但Django在查询中将此代码转换为另一个外键字段的连接。像这样:

SELECT * FROM lightusers INNER JOIN user ON (lightusers.user_id = user.id) WHERE lightusers.user_id IN ( 1, 2, 3)

有没有办法强制Django使用我想要的外键。或原始查询是唯一的选择?

2 个答案:

答案 0 :(得分:2)

  

我需要通过 admin 列中的ID 用户表格获取数据

如果你想要这个,那么你只需要使用admin字段:

light_users = LightUsers.objects.filter(admin__in=[1,2,3])

但这与以下内容不同:

  

我想执行以下查询:

SELECT * FROM lightusers INNER JOIN user ON (lightusers.admin_id = user.id) WHERE lightusers.user_id IN ( 1, 2, 3)

这基本上意味着给我所有lightusers user_id IN(1,2,3)并拥有admin。以ORM方式,可以这样实现:

light_users = LightUsers.objects.filter(
        user_id__in=[1,2,3], #this will filter lightusers.user_id IN ( 1, 2, 3)
        admin__isnull=False  #this will INNER JOIN users on admin and get row having an admin
    )

答案 1 :(得分:0)

最后我放弃了在一个查询中做出这个。并将其分为两部分:

relations = LightUsers.objects.filter(user__in=[1, 2, 3]).values_list('admin_id', 'user_id')
light_users = User.objects.filter(id__in=[relation[0] for relation in relations])

然后合并结果。