使用 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)
【讨论】:
谢谢,编辑正是我想要的。我没有意识到您可以将extra
和filter
方法与&
和|
链接起来。【参考方案2】:
如果您只是摆脱过滤器子句,并使用您的 Postgres 特定函数将该过滤器直接包含到额外的 OR'd 中,这可能会更容易。我认为这已经是 Django ORM 的一个限制。
您可以尝试创建自己的Func expression。一旦你为你的 Postgres 特定函数创建了一个,你就可以使用 Func()、F() 和 Q() 对象的组合来摆脱那个讨厌的 .extra() 函数并将它们很好地链接起来。
【讨论】:
以上是关于使用 Extra 和 Filter 的 Django OR 查询的主要内容,如果未能解决你的问题,请参考以下文章