【问题标题】:Django OR query using Extra and Filter使用 Extra 和 Filter 的 Django OR 查询
【发布时间】: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 连接起来。他为什么要这样做与这个问题无关。

标签: python django orm


【解决方案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() 函数并将它们很好地链接起来。

【讨论】:

    猜你喜欢
    • 2016-01-16
    • 2015-10-17
    • 1970-01-01
    • 1970-01-01
    • 2019-02-06
    • 2010-11-13
    • 1970-01-01
    • 2015-05-02
    • 2021-04-02
    相关资源
    最近更新 更多