simple_tag 和 inclusion_tag 有什么区别?返回 HTML 时怎么转义?能不能改模板变量?开销多大?这篇写几个小标签,把这些问题逐个跑出来。
{% hello "ann" %} → Hi, ann
{% hello name greeting="Yo" %} → Yo, bob
{% hello "cat" as msg %}{{ msg }}{{ msg }} → [Hi, cat][Hi, cat]
↑ as 之后用两次,tag 调用次数: 1
不用 as 写两次,tag 调用次数: 2适合「算一个值输出」。要在同一页多次使用同一个结果,用 as。
返回普通字符串 <b> → <b><i></b> format_html 返回 → <b><i></b> mark_safe 返回(参数未转义!)→ <i><script>x</script></i>
simple_tag 的返回值会经过 conditional_escape:返回 SafeString 才保持原样。
who(无 user 属性的 request) → anon
set_flag 之后同一模板里能读到吗: '[set-by-tag]' ← 写进 context 的变量在当前作用域内有效
在 {% for %} 里 set_flag: '[]' ← 循环里的写入在循环结束后不可见(context 被 push/pop)写上下文会污染模板的变量空间,通常不推荐;确实需要时注意作用域(第 87 篇看块作用域)。
{% item "a" %} → <li>a|</li>
外层变量 site 默认不会传进去: (见上,|后面为空)
{% item_ctx "b" %} takes_context → <li>b|S</li>
循环里 4 次 inclusion_tag,tag 函数调用次数: 4相当于一个「带自己上下文的 include」。
20 处直接写 {{ v }}: 25 µs
20 处 simple_tag {% hello v %}: 29 µs
20 处 inclusion_tag {% item v %}: 201 µs渲染 200 次取中位数,合成对比,SQLite 无关。
ValueError: tag exploded
没有静默吞掉。