所以,我正在尝试加入一堆Q()查询,特别是我希望运算符是用户定义的。
为了做到这一点,我正在尝试使用Q.add(Q,运算符)函数,并将运算符作为输入接收。
但是当我尝试将运算符设置为OR时,我遇到了一种奇怪的行为,如下所述:
q_1 = Q(field_one__id=5)
q_2 = Q(field_two__name='foo')
print q_1
> (AND: ('field_one__id', 5))
print q_2
> (AND: ('field_two__name','foo'))
q_1_and_q_2 = Q()
q_1_or_q_2 = Q()
q_1_and_q_2.connector = q_1_and_q_2.AND # This is the default operator but just in case.
q_1_or_q_2.connector = q_1_or_q_2.OR
# joining both versions using q.add() with the pre-set operator. clone() is used to avoid overriding q_1.
q_1_and_q_2 = q_1.clone().add(q_2, q_1_and_q_2.connector)
q_1_or_q_2 = q_1.clone().add(q_2, q_1_or_q_2.connector)
#printing q_1_and_q_2 works as expected:
print q_1_and_q_2
> (AND: ('field_one__id', 5), ('field_two__name','foo'))
#But printing q_1_or_q_2 shows that q_1 was overridden by q_2
print q_1_or_q_2
> (AND: ('field_two__name','foo'))
有人知道为什么会这样吗?
我认为一个像样的旁路看起来像这样:
from operator import or_, and_
if user_says_op == 'OR':
op = or_
else:
op = and_
q_1_with_q_2_operator_as_input = op(q_1,q_2)
但这样做感觉不对,如果可能的话我宁愿使用Q.add()
。
答案 0 :(得分:0)
发生奇怪的行为是因为q_1
的连接器与add()
方法中指定的连接器不同。如果它们不相同,则返回输入的对象而不是新的连接Q
对象。
示例:
>>> q_1 = Q(field_one__id=5)
>>> q_2 = Q(field_two__name='foo')
>>> q_1.connector = Q.AND
>>> print q_1.clone().add(q_2, Q.AND)
(AND: ('field_one__id', 5), ('field_two__name', 'foo')) # concatenated object
>>> q_1.connector = Q.OR
>>> print q_1.clone().add(q_2, Q.AND)
(AND: ('field_two__name', 'foo')) # inputted data
<强>解决方案强>
在使用q_1
:
add()
的连接器即可
q_1 = Q(field_one__id=5)
q_2 = Q(field_two__name='foo')
q_1.connector = Q.AND
q_1_and_q_2 = q_1.clone().add(q_2, q_1.connector)
q_1.connector = Q.OR
q_1_or_q_2 = q_1.clone().add(q_2, q_1.connector)
print q_1_and_q_2
print q_1_or_q_2
输出:
(AND: ('field_one__id', 5), ('field_two__name', 'foo'))
(OR: ('field_one__id', 5), ('field_two__name', 'foo'))