渲染Jinja2宏而不会打扰模板其余部分的内容

Pas*_*day 9 python jinja2 flask

在我的第一个Flask项目上工作时,我在尝试从Jinja2模板渲染宏时偶然发现了jinja2.exceptions.UndefinedError异常.事实证明,Jinja2在尝试解析确实包含对全局请求对象的引用的模板的其余部分时会生成此异常.

这是我用于测试用例的模板test.html:

<!doctype html>
{% macro test_macro() -%}
  Rendered from macro
{%- endmacro %}
{{ request.authorization }}
Run Code Online (Sandbox Code Playgroud)

Flask代码#1:渲染模板(成功):

@app.route("/test")
def test_view():
    return render_template('test.html')
Run Code Online (Sandbox Code Playgroud)

Flask代码#2:渲染宏(失败):

@app.route("/test")
def test_view():
    test_macro = get_template_attribute('test.html', 'test_macro')
    return test_macro()
Run Code Online (Sandbox Code Playgroud)

如果{{ request.authorization }}从模板中取出,第二次测试将成功执行.

Flask代码#3:使用我在Flask邮件列表存档中找到解决方法(成功):

@app.route("/test")
def test_view():
    t = app.jinja_env.get_template('test.html')
    mod = t.make_module({'request': request})
    return mod.test_macro()
Run Code Online (Sandbox Code Playgroud)

虽然我现在有一个工作代码,但我不知道第二种方法失败的原因让我感到不舒服.为什么当需要只渲染宏时,Jinja2甚至会困扰模板的其余部分呢?

wan*_*ust 1

你说得对,这是金贾那边造成的。get_template_attribute()Flask 中的方法如下所示:

return getattr(current_app.jinja_env.get_template(template_name).module,
               attribute)
Run Code Online (Sandbox Code Playgroud)

因此,它尝试检索模板名称,然后module在生成属性列表之前调用属性来评估该模板。request就您而言, Jinja对该变量的引用仍然未知。有关更多详细信息,请查看Jinja 的environment.py来源