对于循环:
values = [1, 2, 3]
q = Q(pk__in=[]) # generic "always false" value
for val in values:
q |= Q(pk=val)
Article.objects.filter(q)
减少:
from functools import reduce
from operator import or_
values = [1, 2, 3]
q_objects = [Q(pk=val) for val in values]
q = reduce(or_, q_objects, Q(pk__in=[]))
Article.objects.filter(q)
这两个都等价于Article.objects.filter(pk__in=values)
values
当空的时候考虑你想要什么是很重要的。Q()
许多以作为起始值的答案将返回所有内容。Q(pk__in=[])
是一个更好的起始值。它是一个总是失败的 Q 对象,由优化器很好地处理(即使对于复杂的方程)。
Article.objects.filter(Q(pk__in=[])) # doesn't hit DB
Article.objects.filter(Q(pk=None)) # hits DB and returns nothing
Article.objects.none() # doesn't hit DB
Article.objects.filter(Q()) # returns everything
如果您想在为空时返回所有内容values
,您应该 AND with~Q(pk__in=[])
以确保该行为:
values = []
q = Q()
for val in values:
q |= Q(pk=val)
Article.objects.filter(q) # everything
Article.objects.filter(q | author="Tolkien") # only Tolkien
q &= ~Q(pk__in=[])
Article.objects.filter(q) # everything
Article.objects.filter(q | author="Tolkien") # everything
重要的是要记住 that Q()
is nothing,不是一个总是成功的 Q 对象。任何涉及它的操作都会完全放弃它。