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

Eli*_*isa 261 python sql django django-orm django-queryset

我想写一个等同于这个SQL查询的Django查询:

SELECT * from user where income >= 5000 or income is NULL.
Run Code Online (Sandbox Code Playgroud)

如何构造Django queryset过滤器?

User.objects.filter(income__gte=5000, income=0)
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为它AND是过滤器.我想过OR滤器来获得各个查询集的联合.

Lak*_*sad 498

from django.db.models import Q
User.objects.filter(Q(income__gte=5000) | Q(income__isnull=True))
Run Code Online (Sandbox Code Playgroud)

通过文档

  • 如果还有其他一些查询和这个@lakshman 一起怎么办? (2认同)

hob*_*obs 53

因为QuerySets实现了Python __or__运算符(|)或联合,所以它才有效.正如你所期望的,|二进制运算符返回QuerySet如此order_by(),.distinct()和其他的queryset过滤器可上涨了到最后.

combined_queryset = User.objects.filter(income__gte=5000) | User.objects.filter(income__isnull=True)
ordered_queryset = combined_queryset.order_by('-income')
Run Code Online (Sandbox Code Playgroud)

  • "无证件"和"遗产"让我害怕.我认为使用Q对象更安全,详见接受的答案. (18认同)
  • 但是,我可以确认这仍然适用于2014年7月! (3认同)
  • FYI,order_by()和distinct()可以在组合后应用于管道查询集 (2认同)
  • @Oatman:| 操作员已记录在案。请参阅https://docs.djangoproject.com/zh-CN/2.0/ref/models/querysets/:“通常,Q()对象使定义和重用条件成为可能。这允许使用|(构建复杂的数据库查询。 OR)和&(AND)运算符;特别是,否则不可能在QuerySet中使用OR。” 我没有检查早期版本的文档,但是管道操作符至少在Django 1.1.4上有效(只是尝试过)。 (2认同)

joj*_*ojo 17

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

from django.db.models import Q
q1 = User.objects.filter(Q(income__gte=5000) | Q(income__isnull=True))
Run Code Online (Sandbox Code Playgroud)

q2 = User.objects.filter(income__gte=5000) | User.objects.filter(income__isnull=True)
Run Code Online (Sandbox Code Playgroud)

然而,关于更喜欢哪一个似乎存在一些混淆。

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

Django的ORM食谱在这个比较详细谈到,这里是有关部分:


queryset = User.objects.filter(
        first_name__startswith='R'
    ) | User.objects.filter(
    last_name__startswith='D'
)
Run Code Online (Sandbox Code Playgroud)

造成

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%)'
Run Code Online (Sandbox Code Playgroud)

qs = User.objects.filter(Q(first_name__startswith='R') | Q(last_name__startswith='D'))
Run Code Online (Sandbox Code Playgroud)

造成

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%)'
Run Code Online (Sandbox Code Playgroud)

来源:django-orm-cookbook



Fai*_*eed 7

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

一个例子是

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

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


小智 5

为了添加我们在 sql 查询中使用的“OR”或“AND”等条件,我们以这种方式为例

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)))
Run Code Online (Sandbox Code Playgroud)

这相当于这个sql查询

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

我希望您能够正确理解“,”代表“AND”运算符,“|”代表“|” 用于 django 中使用的“OR”运算符。