在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()
答案 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]: []