强制 Django 使用两个外键之一

Force django to use one of two foreign keys

我有一个模型在另一个模型上有两个外键。 数据库结构:

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 使用我想要的外键。或者原始查询是唯一的选择?

I need to get data from user table by ids in admin column

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

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

但这与以下内容不同:

I want to perform query like:

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

这基本上意味着给我所有 lightusersuser_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
    )

好吧,最后我放弃了在一个查询中进行此操作。并将其一分为二:

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])

然后合并结果。