我有一个有趣的Django问题。
请考虑以下事项:
Model.objects.filter(Q(id='test1') and Q(id='test2'))
这会返回预期的结果,但是
Model.objects.filter(Q(id='test1') & Q(id='test2'))
不要!!
这里发生了什么?
答案 0 :(得分:3)
如果你想让Django ORM返回test1和test2,你应该使用:
Model.objects.filter(Q(id='test1') | Q(id='test2'))
Model.objects.filter(Q(id='test1') & Q(id='test2'))
表示返回模型对象,其id为test1,同时为test2。当然,django将返回一个空的QuerySet。
和是Python中的boolean operator。对于操作x and y
,结果为if x is false, then x, else y
。因此Q(id='test1') and Q(id='test2')
等于Q(id='test1')
,这不是您想要的。
& / | 是bitwise and/or operator。
顺便说一句,没有办法覆盖布尔运算符,但您可以通过定义名为&/|
/ __and__
的方法来覆盖类中的__or__
运算符。
下面的是django Q对象[github]的源代码:
class Q(tree.Node):
"""
Encapsulates filters as objects that can then be combined logically (using
& and |).
"""
# Connection types
AND = 'AND'
OR = 'OR'
default = AND
def __or__(self, other):
return self._combine(other, self.OR)
def __and__(self, other):
return self._combine(other, self.AND)
...
答案 1 :(得分:0)
根据以下tutorial
&安培;是二进制AND运算符,如果它存在于两个操作数中,则将一个位复制到结果中。
实施例: 假设a = 60;和b = 13;现在采用二进制格式,它们如下:
a = 0011 1100
b = 0000 1101
(a& b)将给出12,即0000 1100
和Called Logical AND运算符。如果两个操作数都为真,则条件变为真。
示例:(a和b)为真。
所以&在您的查询集上执行二进制加法。有趣。
答案 2 :(得分:0)
我认为你想要OR
,而不是AND
filters = ['test1', 'test2', 'test3', 'test4']
filtered = Model.objects.filter(Q(id = filters[0]))
for f in filters[1:]:
subset = Model.objects.filter(Q(id = f))
filtered = filtered | subset