使用 Extra 和 Filter 的 Django OR 查询

Posted

技术标签:

【中文标题】使用 Extra 和 Filter 的 Django OR 查询【英文标题】:Django OR query using Extra and Filter 【发布时间】:2015-10-06 02:34:01 【问题描述】:

我正在尝试使用 Django 的 ORM 来生成使用额外和过滤方法的查询。像这样的:

Model.objects.filter(clauseA).extra(clauseB).all()

这会生成一个查询,但问题是 filter 子句中的所有内容都与 extra 子句中的所有内容进行了 AND 运算,因此 sql 看起来像:

SELECT * FROM model WHERE clauseA AND clauseB. 

我的问题是,有没有办法更改 Django 中查询的默认组合运算符,以便生成的查询为:

SELECT * FROM model WHERE clauseA OR clauseB. 

【问题讨论】:

您是否只是在寻找or query?(可能重复) 不,这仅适用于过滤器方法中的参数。我需要更改默认组合器,以便从extra() 方法返回的内容与从filter() 方法返回的内容进行“或”运算(而不是目前的“与”)。我在额外方法中拥有的是无法在 Django ORM 中表示且无法用 Q 包装的原生 SQL Model.objects.filter(Q(clauseA) | Q(clauseB)).all() 不是一个有效的解决方案吗?我看不出你为什么需要单独的调用(根据我自己的测试,这里显示的这个过滤器会产生你想要的 sql 输出)。我确信可以更改默认组合器,但我不建议这样做 不,很遗憾,这行不通。我需要使用额外子句的原因是我正在使用一些不会转换为 ORM 的 Postgres 特定函数。因此不能包裹在 Q 中以传递给过滤器方法。 OP 想知道如何将 extra() 子句与 or 而不是 and 连接起来。他为什么要这样做与这个问题无关。 【参考方案1】:

试试Q object

Model.objects.filter(Q(clauseA) | ~Q(clauseB))

编辑

试试这个

Model.objects.filter(clauseA) | Model.objects.extra(clauseB)

【讨论】:

谢谢,编辑正是我想要的。我没有意识到您可以将extrafilter 方法与&| 链接起来。【参考方案2】:

如果您只是摆脱过滤器子句,并使用您的 Postgres 特定函数将该过滤器直接包含到额外的 OR'd 中,这可能会更容易。我认为这已经是 Django ORM 的一个限制。

您可以尝试创建自己的Func expression。一旦你为你的 Postgres 特定函数创建了一个,你就可以使用 Func()、F() 和 Q() 对象的组合来摆脱那个讨厌的 .extra() 函数并将它们很好地链接起来。

【讨论】:

以上是关于使用 Extra 和 Filter 的 Django OR 查询的主要内容,如果未能解决你的问题,请参考以下文章

django使用原生SQL的方法

在django中,执行原始sql语句

Django ORM - 模拟 values().filter() 链

将文字百分号传递给 QuerySet.extra()

django中使用原生sql

django中使用原生sql