LEFT OUTER JOIN以及Django中的其他定义

时间:2009-05-20 23:50:08

标签: django django-models

类Project(models.Model):         users = models.ManyToManyField(User,through ='Project_User')

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

我希望,这是可能的,但我不知道如何,但是......

感谢您的帮助!

2 个答案:

答案 0 :(得分: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)的使用相矛盾。

答案 1 :(得分:0)

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

这应该为您提供当前用户的所有项目的查询集,不包括那些属性值为True的当前用户的Project_User

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