始终为假Q对象

时间:2016-03-09 14:08:16

标签: django

在Django ORM中,如何创建始终为False的Q对象?

这类似于关于always True Q objects的问题,但反之亦然。

请注意,这不起作用:

Foobar.objects.filter(~Q()) # returns a queryset which gives all objects

为什么我需要Q对象而不是简单的False值?这样我就可以将它与其他Q值结合起来,例如:

condition = always_true_q_object
if something_or_other:
    condition = condition | foobar_that_returns_a_q_object()
if something_or_other2:
    condition = condition | foobar_that_returns_a_q_object2()

3 个答案:

答案 0 :(得分:12)

怎么样:

Q(pk__isnull=True)

Q(pk=None)

看起来很骇人听闻,但似乎有效。例如:

>>> FooBar.objects.filter(Q(x=10)|Q(pk__isnull=True))
[<FooBar: FooBar object>, ...]
>>> FooBar.objects.filter(Q(x=10)&Q(pk__isnull=True))
[]

但请注意,当空格Q()时,它并不像您预期​​的那样有效。

>>> FooBar.objects.filter(Q()|Q(pk__isnull=True))
[]

解决方法可能是使用Q(pk__isnull=False)作为“始终为真Q&#39;”

>>> FooBar.objects.filter(Q(pk__isnull=False)|Q(pk__isnull=True))
[<FooBar: FooBar object>, ...]
>>> FooBar.objects.filter(Q(pk__isnull=False)&Q(pk__isnull=True))
[]

答案 1 :(得分:7)

我刚用Q(pk__in=[])来表示这个习语。

感觉不那么hacky,并且可能会让DBMS的优化器更多地使用。

答案 2 :(得分:6)

我没有足够的声誉来评论,但Sam Mason的回答(Q(pk__in=[]))的优势在于,如果单独使用,它甚至不会执行数据库查询。 Django(v1.10)似乎很聪明,可以识别出条件不可满足,并且在不询问数据库的情况下返回空的查询集。

$ ./manage.py shell_plus

In [1]: from django.db import connection

In [2]: FooBar.objects.filter(Q(pk__in=[]))
Out[2]: <QuerySet []>

In [3]: connection.queries
Out[3]: []