使用Django模板标签是否执行Querysets?
Does the use of Django template tags execute Querysets?
我正在阅读 Django 2 by Example 这本书,我一度感到困惑有一行 {% with comments.count as total_comments %}
作者继续解释
We are using the Django ORM in the template, executing the QuerySet comments.count()
...The {% with %} template tag is useful to avoid
hitting the database or accessing expensive methods multiple times.
我认为模板正在使用传递给它们的任何上下文并且没有发生数据库访问?
I thought templates are using whatever context is passed to them and no database access occurs?
它使用通过上下文传递的内容。但是 QuerySet
是 延迟执行的 。这意味着,例如,如果您传递 MyModel.objects.all()
,它将 不会 进行查询,或者至少不会立即进行查询。
只有当您“使用”查询集时,例如通过遍历它或计算查询集的长度,您才会对数据库。因此,一个模板可以触发多个数据库查询。事实上 N+1 个问题 通常是由模板迭代一个 QuerySet
对象,然后查询相关管理器引起的。
QuerySet
上的 .count()
也会急切求值,因此如果您有 somequeryset
,并且您调用 .count()
将触发数据库查询。如果这是在循环中或在模板中的不同位置完成的,那么它将减少对数据库的更多查询。通过使用 {% with …=… %}
语句,您将在模板计算 {% with …=… %}
部分时进行查询,然后您可以多次重用该变量。
我正在阅读 Django 2 by Example 这本书,我一度感到困惑有一行 {% with comments.count as total_comments %}
作者继续解释
We are using the Django ORM in the template, executing the QuerySet
comments.count()
...The {% with %} template tag is useful to avoid hitting the database or accessing expensive methods multiple times.
我认为模板正在使用传递给它们的任何上下文并且没有发生数据库访问?
I thought templates are using whatever context is passed to them and no database access occurs?
它使用通过上下文传递的内容。但是 QuerySet
是 延迟执行的 。这意味着,例如,如果您传递 MyModel.objects.all()
,它将 不会 进行查询,或者至少不会立即进行查询。
只有当您“使用”查询集时,例如通过遍历它或计算查询集的长度,您才会对数据库。因此,一个模板可以触发多个数据库查询。事实上 N+1 个问题 通常是由模板迭代一个 QuerySet
对象,然后查询相关管理器引起的。
QuerySet
上的 .count()
也会急切求值,因此如果您有 somequeryset
,并且您调用 .count()
将触发数据库查询。如果这是在循环中或在模板中的不同位置完成的,那么它将减少对数据库的更多查询。通过使用 {% with …=… %}
语句,您将在模板计算 {% with …=… %}
部分时进行查询,然后您可以多次重用该变量。