2009-05-20 113 views
1

类项目(models.Model)补充定义: 用户= models.ManyToManyField(用户,通过= 'Project_User')LEFT OUTER JOIN在Django的

class Project_User(models.Model): 
    project = models.ForeignKey('Project') 
    user = models.ForeignKey(User) 
    property = models.BooleanField() 

并不是所有的项目都有自己的Project_User行。

事情,我需要的是获取当前用户的字段“属性”!= true或当前用户的Project_User行不存在的所有项目的查询集。有没有办法使用django的ORM来做到这一点?因此,我需要Queryset对象来为其应用一些其他过滤器。

使用自定义SQL我可以做到这一点。当前用户是否有ID = = XXXX:

SELECT * FROM "app_project" LEFT OUTER JOIN "app_project_user" 
ON ("app_project"."id" = "app_project_user"."project_id" 
    AND ("app_project_user"."user_id" = XXXX OR "app_project_user"."user_id" IS NULL)) 
WHERE ("app_project_user"."property" = false OR "app_project_user"."property" IS NULL); 

我希望,这是可能的,但我不知道怎么回事,但..

感谢您的帮助!

回答

0

东西沿着

p = Projects.objects.filter(users=current_user) 
p = p.exclude(project_user__user=current_user, 
       project_user__property=True) 

线这应该给你的所有项目的查询集为当前用户,不包括对其中有对谁的属性值当前用户Project_User是真

更多信息:http://docs.djangoproject.com/en/dev/topics/db/queries/#lookups-that-span-relationships

+0

这对我不好,因为ORM生成子查询。当我有几个bool字段时 - 一个字段的子查询不起作用。 – ramusus 2009-05-21 09:45:52

3

对于复杂查找(和任何查找,本质上,涉及OR),我推荐Django's Q operator

在这种情况下,查询可能类似于:

from django.db.models import Q 

q = (Q(project_user=my_current_user) | Q(project_user=None)) & \ 
    (Q(project_user__property=False) | Q(project_user__property=None)) 
projects = Project.objects.filter(q) 

在这种情况下,不要忘记,表明NULL允许您property领域:

class Project_User(models.Model): 
    # ... as above, then: 
    property= models.BooleanField(null=True) 

否则,Django的将针对property字段发出CREATE TABLE sql,该字段专门指示null不被允许("property" bool NOT NULL),这将与使用Q(project_user__property=None)相抵触。

+0

感谢它变得更加清晰。一个问题,我看到: Project.objects.filter(Q(project_user = my_current_user)| Q(project_user = None))。 转变为 SELECT COUNT(*)FROM “app_project” LEFT OUTER JOIN “app_project_user” ON( “app_project”。 “ID”= “app_project_user”。 “PROJECT_ID”)LEFT OUTER JOIN “AUTH_USER” ON( “app_project_user” “user_id”=“auth_user”。“id”)WHERE(“app_project_user”。“user_id”= 10或“auth_user”。“id”IS NULL)。 我不明白什么第二个LEFT OUTER JOIN与auth_user表。它返回另一个结果,然后用1连接。有什么办法可以避免它? – ramusus 2009-05-21 09:42:58