【发布时间】:2012-12-22 12:30:31
【问题描述】:
Django的built-in include tag和custom inclusion tags有什么区别?
我已经阅读了文档,两者似乎都实现了相同的目标:渲染一个模板并传递一个上下文或变量。
【问题讨论】:
Django的built-in include tag和custom inclusion tags有什么区别?
我已经阅读了文档,两者似乎都实现了相同的目标:渲染一个模板并传递一个上下文或变量。
【问题讨论】:
它们有不同的用途。 include 标记仅包含来自现有模板的完整内容且未经修改。自定义包含标记将上下文传递给一个函数,该函数可以包含在将上下文传递给模板之前对其进行操作的逻辑。
例如,也许我有一个将在多个页面上显示的面板。面板的模板需要通过上下文传递一些特定的查询。包含面板的页面不需要这些上下文变量来做其他任何事情。如果我在include 标记中包含面板模板,我将不得不在包含面板的每个视图中编写这些查询并将它们作为上下文变量传递。
或者,我可以编写一个自定义包含标签,其中包含查询并将它们传递给面板的模板。通过使用自定义包含标记,我不需要重复代码以在包含面板的每个视图中生成其上下文。我的视图将包含更少的代码,并且不会因为仅由面板使用的上下文变量而变得杂乱无章。
尽管您在某种意义上是正确的,即简单地传递未经处理的上下文的自定义包含标记与include 标记相同。
【讨论】:
include 之间的区别甚至比您最初想象的要小,因为使用include 您可以做到{% include "template.html" with var1='foo' var2='bar' %}。我不记得with 是否一直是include 的一部分,但它与包含标签的目的部分重叠。
需要将模板分成更小的文件?使用 include 标签(为了可读性和可维护性以及 DRY)
需要在渲染模板之前包含更多代码?使用inclusion tags(获取更多数据,添加一些业务逻辑。它真的很像另一个没有url的小视图。它就像一个模板函数)。
【讨论】:
原则上,dgel 和 YardenST 的回答提出的观点是正确的。此外,查看 django 的代码可以很好地了解这两个选项在性能方面的比较。
使用default template loaders时,两者绝对没有区别。两者最终都会调用InclusionTag render() 函数,然后调用模板Loader get_contents() 从文件系统打开模板文件。 render() 只缓存文件,以防它在模板中用于循环。
附带说明,使用django.template.loaders.cached.Loader 可能会产生性能差异。
最后,关于 dgel 的建议,即在不同视图中使用包含标记作为通用上下文:当 html 标记位于跨许多视图,通过使用ContextMixin。这是一个非常常见的渲染场景,例如。基本模板中的主菜单。
【讨论】:
django.template.loaders.cached.Loader 时可能会出现性能差异。这背后的确切原因是什么?
最近刚遇到这个问题,因为我试图找到最好的路线 - include 与 inclusion tag - 当没有真正的额外逻辑可能进入 inclusion tag 时。
而我选择inclusion tag的原因如下:
<!-- include -->
{% include "path/to/funky.html" with arg1=arg1 arg2=arg2 %}
对比
<!-- inclusion tag -->
{% funky arg1 arg2 %}
inclusion tag 不能从父视图继承变量,使其更能抵御奇怪的错误【讨论】: