Django 模板标签的使用是不是执行查询集?

Posted

技术标签:

【中文标题】Django 模板标签的使用是不是执行查询集?【英文标题】:Does the use of Django template tags execute Querysets?Django 模板标签的使用是否执行查询集? 【发布时间】:2020-04-02 16:07:31 【问题描述】:

我正在阅读 Django 2 by Example 一书,我一度感到困惑,有一行 % with comments.count as total_comments % 作者继续解释

我们在模板中使用 Django ORM,执行 QuerySet comments.count()...% with % 模板标签有助于避免 多次访问数据库或访问昂贵的方法。

我认为模板正在使用传递给它们的任何上下文并且没有发生数据库访问?

【问题讨论】:

QuerySets 是懒惰的,因此只有在你“消费”这些时才会执行。所以模板可以是执行由QuerySet“代表”的查询的“触发器”。 【参考方案1】:

我认为模板正在使用传递给它们的任何上下文并且没有发生数据库访问?

它使用通过上下文传递的内容。但是QuerySet懒惰地执行的。这意味着,例如,如果您传递 MyModel.objects.all(),它将不会进行查询,或者至少不会立即进行。

只有当您“使用”查询集时,例如通过迭代它,或通过计算查询集的长度,您才会对数据库进行查询。因此,一个模板可以触发多个数据库查询。事实上,N+1 个问题通常是由模板迭代一个QuerySet 对象,然后查询相关的管理器造成的。

QuerySet 上的.count() 也会被热切评估,因此如果您有somequeryset,并且您调用.count(),这将触发数据库查询。如果这是在循环中或在模板中的不同位置完成的,那么它将因此减少对数据库的更多查询。通过使用% with …=… % 语句,您将在模板评估% with …=… % 部分时进行查询,然后您可以多次重复使用该变量。

【讨论】:

以上是关于Django 模板标签的使用是不是执行查询集?的主要内容,如果未能解决你的问题,请参考以下文章

Django模板标签搜索通过for循环寻找特定对象,如果没有找到则默认

你可以制作一个返回查询集的自定义模板标签吗?如果是,如何? - 姜戈

Django 模板和引导表

如何比较 Django 模板中的两个查询集?

Django:如何使用查询集并在模板中显示结果?

如何访问由 AJAX 响应返回到模板的查询集 - Django