在 Django 中使用“.filter().filter().filter()...”有缺点吗?

Posted

技术标签:

【中文标题】在 Django 中使用“.filter().filter().filter()...”有缺点吗?【英文标题】:Is there a downside to using ".filter().filter().filter()..." in Django? 【发布时间】:2011-04-13 14:19:20 【问题描述】:

以下两个调用是否解析为 Django 中的等效 SQL 查询?

链接多个调用

Model.objects \
.filter(arg1=foo) \
.filter(arg2=bar) \
...

将所有参数包装在一起:

Model.objects \
.filter(arg1=foo, arg2=bar)

我希望代码可读(过滤器调用比我展示的要多),但前提是不牺牲性能。

【问题讨论】:

这能回答你的问题吗? Chaining multiple filter() in Django, is this a bug? 【参考方案1】:

更新:

忽略这个答案。看到这个更好,@ 987654321@。 感谢@Sam 的提醒。

旧答案:

以下两个调用是否解析为 Django 中的等效 SQL 查询?

简短的回答:是的。它们将生成等效查询。

我用我正在使用的模型验证了这一点。产生的查询在功能上是相同的。不同的filter 条件在查询中一起ANDed。

我希望代码可读(过滤器调用比我展示的要多),但前提是不牺牲性能。

实现可读性的一种方法是使用字典来收集所有过滤条件。例如

conditions = dict(arg1 = foo, arg2 = bar, ....)
conditions.update(argN = baz)

Model.objects.filter(**conditions)

【讨论】:

这对于多值关系是不正确的。在适当的条件下,他们将生成 不同 的查询,并具有 不同 的结果。请参阅此答案和链接文档 - ***.com/a/8164920【参考方案2】:

除了 Manoj 的回答之外,下面是分析为 QuerySet 对象生成的 sql 的方法:

result1 = SomeModel.objects.filter(field1=100, field2=200)
print "Result1", results1.query

result2 = SomeModel.objects.filter(field1=100).filter(field2=200)
print "Result2", result2.query

【讨论】:

assert 语句可能并非每次都有效。我尝试时生成的查询中AND子句的顺序不同。 是的,你是对的,刚刚测试过了。从答案中删除断言。

以上是关于在 Django 中使用“.filter().filter().filter()...”有缺点吗?的主要内容,如果未能解决你的问题,请参考以下文章

在django中使用django_debug_toolbar

Django:在管理界面中使用 TinyMCE 4

在 django-crispy 按钮名称中使用 django 模板变量

使用 django-import-export 在 django 迁移中的外键

如何使用 Django Rest Framework 在 Django 中进行操作日志记录

如何在 Django 中使用模式?