对于循环:
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操作~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
重要的是要记住,什么都不Q()
是,不是一个总是成功的Q对象。涉及此操作的任何操作都会将其完全删除。