2015-04-03 40 views
0

我有一个模型,在另一个外键上。 DB结构:强制django使用两个外键之一

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

+0

触发一个字段的使用情况是什么? – karthikr 2015-04-03 18:37:53

+0

@karthikr我需要从**用户**表中获取**用户**表中的数据 – 2015-04-03 18:47:02

回答

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

然后合并结果。

+0

您可以使用如下子查询将其优化为一个查询: 'light_users = User.objects.filter(id__in = LightUsers.objects .filter(user__in = [1,2,3])。values_list('admin_id',flat = True))' – Todor 2015-04-06 16:05:34

+0

是的,但在这种情况下,我将失去管理员和用户之间的连接。无法跟踪哪个用户与哪个管理员=) – 2015-04-06 16:17:42

2

我需要从用户表由IDS在管理列中获取数据

如果你想要这个,那么你只需要使用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) 

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

'light_users = LightUsers.objects.filter(user__in = [1,2,3],admin__isnull = False)'不加入表格。它只是增加'和cw_core_lightusers.admin_id不是NULL'。之后,当我执行light_users中的light_user:name = light_user.user.username时,这会查询light_users中的每个元素。而这正是我想要避免的。 – 2015-04-04 06:51:11

+1

'INNER JOIN user ON(lightusers.admin_id = user.id)'与'lightusers.admin_id IS NOT NULL'在返回的'lightusers'方面相同(两者都只会返回带有'admins'的行。但是如果你想要实际上添加'INNER JOIN',然后将其改为'admin__id__isnull = False'。但是在所有这些'INNER JOIN' **不会填充'user'字段。如果你想'user'字段填充''admin''数据,你不能用ORM *(除了'.raw')*这样做,但你可以做的是'LightUsers.objects.filter(admin__in = [1,2,3])。select_related 'admin')',然后使用'light_user.admin.username'代替。 – Todor 2015-04-04 08:47:57

+0

用2个查询做出来。感谢您的帮助 – 2015-04-06 15:57:30