构建后是不是可以修改 Django Q() 对象?

Posted

技术标签:

【中文标题】构建后是不是可以修改 Django Q() 对象?【英文标题】:Is it possible to modify Django Q() objects after construction?构建后是否可以修改 Django Q() 对象? 【发布时间】:2014-10-28 02:11:22 【问题描述】:

构造后是否可以修改 Django Q() 对象?我像这样创建一个 Q() 对象:

q = Q(foo=1)

以后是否可以将q 更改为与我构建时相同:

q2 = Q(foo=1, bar=2)

?我能找到的Django docs 中没有提到这样的接口。

我正在寻找类似的东西:

Q.append_clause(bar=2)

【问题讨论】:

“与构造相同”究竟是什么意思?你的意思是动态修改 q 对象吗? @karthikr:更新问题以更好地描述我在寻找什么。 好的。 PerrinHarkins 的答案就是您正在寻找的答案。 【参考方案1】:

您可以使用它们的add 方法将 Q 对象添加在一起。例如:

>>> q = Q(sender=x)
>>> q.add(Q(receiver=y), Q.AND)

add的第二个参数是连接器,也可以是Q.OR

编辑:我的回答只是按照 Perrin Harkins 的建议采取不同的方式,但关于您的其他问题,关于 filter 的不同行为取决于您构建查询的方式,您不必如果您加入 Q 对象,则不必担心。我的示例等价于filter(sender=x, receiver=y),而不是filter(sender=x).filter(receiver=y),因为Q 对象,据我在快速测试中所见,对子句执行立即AND 并且没有filter 的特殊行为多值关系。

在任何情况下,没有什么比查看 SQL 并确保它在您的特定查询中确实执行相同操作更重要的了。

【讨论】:

【参考方案2】:

您可以创建另一个 Q() 对象并将它们组合在一起: q2 = q & Q(bar=2)

【讨论】:

你确定这在语义上是相同的吗?很可能是这样,但我知道可能会有问题。例如,调用.filter(Q(parent__foo=1)).filter(Q(parent__bar=1)).filter(Q(parent__foo=1, parent__bar=1)) 不同,我不想与这样的事情发生冲突。 是的,它们是相同的。重要的是是否有两个 .filter 调用或只有一个。

以上是关于构建后是不是可以修改 Django Q() 对象?的主要内容,如果未能解决你的问题,请参考以下文章

Django:为相关表构建动态 Q 查询

使用 Q-Objects 在 Django 中动态构建复杂查询

Django/Python DRY:使用 Q 对象和模型属性时如何避免重复代码

在Django Q对象中查找最新日期

为sql视图构建一个Q对象

django数据查询之F查询和Q查询