【问题标题】:Difference between using 'and' and using '&' in Django ORM在 Django ORM 中使用 'and' 和使用 '&' 的区别
【发布时间】:2019-07-07 07:00:56
【问题描述】:

当我使用 and&

时,我的查询会显示不同的结果
criteria1 = Q(id__gte=802, id__lte=1000)
criteria2 = Q(country_id__contains='UK')

我一直在用:

q = Mymodel.objects.filter(criteria1 & criteria2)

但在这种特殊情况下,当我使用 & 时,它总是输出一行。 (我还检查了 print q.query(),查询结果很好)

但是,当我使用 and 而不是 & 时。查询给出正确的输出

q = Mymodel.objects.filter(criteria1 and criteria2)

幕后究竟发生了什么?

【问题讨论】:

  • and 不是专门为Q 对象实现的运算符。它将被普通的 Python 规则评估为criteria1 if not criteria1 else criteria2

标签: python django django-orm


【解决方案1】:

正确的是criteria1 & criteria2criteria1 and criteria2 使用标准 Python 布尔逻辑,将被评估为 criteria2,而 criteria1 & criteria2 使用重载的 __and__ 方法并构造正确的复合 Q 对象:

In [1]: from django.db.models import Q                                                                                                                                                                                                                                                                                                                        

In [2]: criteria1 = Q(id__gte=802, id__lte=1000)                                                                                                                                                                                                                                                                                                              

In [3]: criteria2 = Q(country_id__contains='UK')                                                                                                                                                                                                                                                                                                              

In [4]: criteria1 & criteria2                                                                                                                                                                                                                                                                                                                                 
Out[4]: <Q: (AND: ('id__gte', 802), ('id__lte', 1000), ('country_id__contains', 'UK'))>

In [5]: criteria1 and criteria2                                                                                                                                                                                                                                                                                                                               
Out[5]: <Q: (AND: ('country_id__contains', 'UK'))>

【讨论】:

  • 感谢您澄清这一点......使用 and 是完全错误的。当我使用 & 并在 mysql 中运行相同的原始查询时,它返回多行但 orm 返回单行! ...这个问题应该包含在其他线程中吗?
  • 是的,请。创建一个新问题并包含实际代码和 SQL 查询
【解决方案2】:

Q 对象定义魔术方法__or____and__。这些函数允许覆盖 &amp; 数学和 | 操作。检查this document

如果您想了解and&amp; 之间的区别,请参阅this question

这是Q object code。你可以找到下面的代码。

class Q(tree.Node):
    def __or__(self, other):
        return self._combine(other, self.OR)

    def __and__(self, other):
        return self._combine(other, self.AND)

【讨论】:

  • 没有。 __or____and__ 映射到 |&amp;,而不是 orand
  • 我弄错了。对不起。并感谢您的 cmets。 @丹尼尔罗斯曼
猜你喜欢
  • 2019-04-13
  • 2014-07-18
  • 2019-03-12
  • 1970-01-01
  • 1970-01-01
  • 2015-09-23
  • 1970-01-01
  • 2011-05-05
  • 2012-05-25
相关资源
最近更新 更多