如何在django queryset中执行OR条件?

我想写一个Django查询等价于下面的SQL查询:

SELECT * from user where income >= 5000 or income is NULL.

如何构造Django queryset过滤器?

User.objects.filter(income__gte=5000, income=0)

这不起作用,因为它ANDs过滤器。我想OR过滤器,以获得单个查询集的联合。

255453 次浏览
from django.db.models import Q
User.objects.filter(Q(income__gte=5000) | Q(income__isnull=True))

via Documentation

因为QuerySets实现是Python的__or__操作符(|)或联合,所以它可以工作。正如你所期望的那样,|二进制操作符返回QuerySet,因此order_by().distinct()和其他查询集过滤器可以附加到结尾。

combined_queryset = User.objects.filter(income__gte=5000) | User.objects.filter(income__isnull=True)
ordered_queryset = combined_queryset.order_by('-income')

更新2019-06-20:现在在Django 2.1 QuerySet API参考中完整地记录了这一点。更多的历史讨论可以在django项目票#21333中找到。

现有的答案中已经提到了这两个选项:

from django.db.models import Q
q1 = User.objects.filter(Q(income__gte=5000) | Q(income__isnull=True))

而且

q2 = User.objects.filter(income__gte=5000) | User.objects.filter(income__isnull=True)

然而,对于更喜欢哪一个,似乎有一些困惑。

关键是它们在SQL级别上是相同的,所以随意选择你喜欢的!

Django ORM烹饪书详细讨论了这一点,以下是相关部分:


queryset = User.objects.filter(
first_name__startswith='R'
) | User.objects.filter(
last_name__startswith='D'
)

导致

In [5]: str(queryset.query)
Out[5]: 'SELECT "auth_user"."id", "auth_user"."password", "auth_user"."last_login",
"auth_user"."is_superuser", "auth_user"."username", "auth_user"."first_name",
"auth_user"."last_name", "auth_user"."email", "auth_user"."is_staff",
"auth_user"."is_active", "auth_user"."date_joined" FROM "auth_user"
WHERE ("auth_user"."first_name"::text LIKE R% OR "auth_user"."last_name"::text LIKE D%)'

而且

qs = User.objects.filter(Q(first_name__startswith='R') | Q(last_name__startswith='D'))

导致

In [9]: str(qs.query)
Out[9]: 'SELECT "auth_user"."id", "auth_user"."password", "auth_user"."last_login",
"auth_user"."is_superuser", "auth_user"."username", "auth_user"."first_name",
"auth_user"."last_name", "auth_user"."email", "auth_user"."is_staff",
"auth_user"."is_active", "auth_user"."date_joined" FROM "auth_user"
WHERE ("auth_user"."first_name"::text LIKE R% OR "auth_user"."last_name"::text LIKE D%)'

来源:django-orm-cookbook


只是为附加到Q对象的多个过滤器添加这个,如果有人可能正在寻找它。 如果提供了Q object,它必须在任何关键字参数的定义之前。否则它是一个无效的查询。你做这件事的时候要小心。

一个例子是

from django.db.models import Q
User.objects.filter(Q(income__gte=5000) | Q(income__isnull=True),category='income')

这里考虑了OR条件和带有收入类别的过滤器

为了添加像“;或”这样的条件;或“;这样;正如我们在SQL查询中使用的那样,我们以这种方式作为一个例子

from django.db.models import Q
Poll.objects.get(Q(question__startswith='Who'),Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)))

这相当于这个SQL查询

SELECT * from polls WHERE question LIKE 'Who%'
AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06')

我希望你能正确理解这一点,即","是"和"操作员和“|”;是“or”;在django中使用的运算符。