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

时间:2014-02-03 07:08:10

标签: python flask jinja2

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

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

<!doctype html>
{% macro test_macro() -%}
  Rendered from macro
{%- endmacro %}
{{ request.authorization }}

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

@app.route("/test")
def test_view():
    return render_template('test.html')

Flask code#2:渲染宏(失败):

@app.route("/test")
def test_view():
    test_macro = get_template_attribute('test.html', 'test_macro')
    return test_macro()

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

Flask code#3:使用workaround I found in the Flask mailing list archive(成功):

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

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

1 个答案:

答案 0 :(得分:0)

你是绝对正确的,它是在金贾方面造成的。 Flask中的方法get_template_attribute()如下所示:

return getattr(current_app.jinja_env.get_template(template_name).module,
               attribute)

因此它尝试检索模板名称,然后,在生成属性列表之前,调用属性module评估此模板。在您的情况下,Jinja对变量request的引用仍然未知。有关详细信息,请查看Jinja's environment.py sources