我有一个有趣的 Django 问题。
考虑以下:
Model.objects.filter(Q(id='test1') and Q(id='test2'))
这会返回预期的结果,但是
Model.objects.filter(Q(id='test1') & Q(id='test2'))
才不是!!
这里发生了什么?
我有一个有趣的 Django 问题。
考虑以下:
Model.objects.filter(Q(id='test1') and Q(id='test2'))
这会返回预期的结果,但是
Model.objects.filter(Q(id='test1') & Q(id='test2'))
才不是!!
这里发生了什么?
如果你想让 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中的布尔运算符。对于操作x and y
,结果是if x is false, then x, else y
。因此Q(id='test1') and Q(id='test2')
等于Q(id='test1')
,这不是你想要的。
&/| 是按位和/或运算符。
顺便说一句,没有办法覆盖布尔运算符,但您可以&/|
通过定义一个名为__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)
...
根据以下教程
& 是一个二进制 AND 运算符,如果它存在于两个操作数中,则将其复制到结果中。
示例:假设 a = 60;和 b = 13; 现在以二进制格式,它们将如下所示:
一个 = 0011 1100
b = 0000 1101
(a & b) 将给出 12 即 0000 1100
和称为逻辑与运算符。如果两个操作数都为真,则条件为真。
示例:(a 和 b)为真。
所以 & 在你的查询集上执行二进制加法。有趣的。
我想你想要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