1

我有一个有趣的 Django 问题。

考虑以下:

Model.objects.filter(Q(id='test1') and Q(id='test2'))

这会返回预期的结果,但是

Model.objects.filter(Q(id='test1') & Q(id='test2'))

才不是!!

这里发生了什么?

4

3 回答 3

4

如果你想让 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)
    ...
于 2013-10-25T01:47:42.987 回答
0

根据以下教程

& 是一个二进制 AND 运算符,如果它存在于两个操作数中,则将其复制到结果中。

示例:假设 a = 60;和 b = 13; 现在以二进制格式,它们将如下所示:

一个 = 0011 1100

b = 0000 1101

(a & b) 将给出 12 即 0000 1100

和称为逻辑与运算符。如果两个操作数都为真,则条件为真。

示例:(a 和 b)为真。

所以 & 在你的查询集上执行二进制加法。有趣的。

于 2013-10-25T01:19:39.723 回答
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
于 2013-10-25T04:02:39.523 回答