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 % 模板标签有助于避免 多次访问数据库或访问昂贵的方法。
我认为模板正在使用传递给它们的任何上下文并且没有发生数据库访问?
【问题讨论】:
QuerySet
s 是懒惰的,因此只有在你“消费”这些时才会执行。所以模板可以是执行由QuerySet
“代表”的查询的“触发器”。
【参考方案1】:
我认为模板正在使用传递给它们的任何上下文并且没有发生数据库访问?
它使用通过上下文传递的内容。但是QuerySet
是懒惰地执行的。这意味着,例如,如果您传递 MyModel.objects.all()
,它将不会进行查询,或者至少不会立即进行。
只有当您“使用”查询集时,例如通过迭代它,或通过计算查询集的长度,您才会对数据库进行查询。因此,一个模板可以触发多个数据库查询。事实上,N+1 个问题通常是由模板迭代一个QuerySet
对象,然后查询相关的管理器造成的。
QuerySet
上的.count()
也会被热切评估,因此如果您有somequeryset
,并且您调用.count()
,这将触发数据库查询。如果这是在循环中或在模板中的不同位置完成的,那么它将因此减少对数据库的更多查询。通过使用% with …=… %
语句,您将在模板评估% with …=… %
部分时进行查询,然后您可以多次重复使用该变量。
【讨论】:
以上是关于Django 模板标签的使用是不是执行查询集?的主要内容,如果未能解决你的问题,请参考以下文章
Django模板标签搜索通过for循环寻找特定对象,如果没有找到则默认