【问题标题】:Are chained QuerySet filters equivalent to defining multiple fields in a single filter with the Django ORM?链式 QuerySet 过滤器是否等同于使用 Django ORM 在单个过滤器中定义多个字段?
【发布时间】:2012-04-21 18:58:13
【问题描述】:

过滤查询集时,我想知道以下是否等效。

User.objects.filter(username='josh').filter(email__startswith='josh')
User.objects.filter(username='josh', email__startswith='josh')

我无法想象生成的 SQL 在两者之间会有什么不同。文档似乎也没有提到任何差异。

【问题讨论】:

  • 但是你得到不同的结果?
  • 目前没有我能想到的例子,返回不同的结果。但我似乎记得在某些时候存在差异,最近才想起我想追踪是否存在差异。我问的是一般意义上的问题,没有具体的例子。
  • 绝对没有区别。

标签: django django-models filtering


【解决方案1】:

您可以在 shell 中执行这些查询并打印出生成的 SQL,如下所示:

>>> print User.objects.filter(username='josh').filter(email__startswith='josh').query

我测试了一个与您一样的类似查询,生成的 SQL 代码没有任何区别。两个语句最终都使用相同的 WHERE 语句。

此外,在这种情况下,无论是链接过滤器还是一步应用它们,都不会有任何区别。

但在某些情况下,过滤顺序很重要。 看看here 和here。

【讨论】:

  • 没有区别,只是确认了,尽管我认为它不应该。也可以通过 django.db.connection.queries 检查实际的 SQL,但.query() 总是更容易。
  • @okm,我用 .query 来检查一些简单的查询,没有区别。但正如 Jingo 指出的那样,显然您对跨度关系应用过滤的顺序会产生影响。不过文档有些混乱。
  • @JoshSmeaton 是的,您可以更新有关混淆部分的问题。对于跨区查找,每个过滤器/排除都单独附加连接,然后生成的查询取决于实际的排序和查找字段。
  • @okm,但与链式过滤器相比,效果是仅由于排序,还是在单个 filter 中使用多个 kwargs?
  • @JoshSmeaton 我认为主要是后者带有跨区查找。排序可能会改变生成的 SQL 中的 WHERE 条件,但不一定会改变结果;跨区查找,在分离的过滤器中,总是引入额外的连接,从而改变结果。
【解决方案2】:

Django QuerySets 是惰性的,正在运行:

User.objects.filter(username='josh').filter(email__startswith='josh')

甚至

a = User.objects.filter(username='josh')
a = a.filter(email__startswith='josh')

只产生一个数据库查询,当您尝试访问您的数据时执行该查询。此类查询同意 where 子句中的所有过滤器和排除项。

【讨论】:

  • 我知道他们很懒。我正在尝试讨论使用多个 filters 或单个 filter 与多个 kwargs 之间的区别(如果存在的话)。
猜你喜欢
  • 2020-12-24
  • 1970-01-01
  • 2022-12-10
  • 2014-07-13
  • 2020-06-06
  • 2023-03-13
  • 2013-09-08
  • 2018-10-09
  • 1970-01-01
相关资源
最近更新 更多