在Jinaj2.Template.render()中访问烧瓶方法

时间:2020-09-11 04:23:10

标签: python flask jinja2

说我们有一个烧瓶模板,

{% extends "layout.html" %}

{% block body %}

<div class="container page-container">
{% with messages = get_flashed_messages() %}
  {% if messages %}
    <ul class=flashes>
    {% for message in messages %}
      <li>{{ message }}</li>
    {% endfor %}
    </ul>
  {% endif %}
{% endwith %}
</div>

{% endblock %}

我们可以使用flask.render_template()函数来渲染该模板,并使用以下代码显示Flash消息:

from flask import flash, render_template

@timesheet_billing.route('/timesheet-billing')
def timesheet_billing_select_job():
    jobs = get_open_jobs()
    flash('A job was not selected!')
    return render_template('timesheet_billing/index.html', jobs = jobs) 

但是,如果我们使用Jinja2的模板类函数jinja2.Template.render()和如下代码来渲染它:

from flask import flash
import jinja2

env = jinja2.Environment(loader=jinja2.PackageLoader('templates'))
index_temp = env.get_template('index.html')

@timesheet_billing.route('/timesheet-billing')
def timesheet_billing_select_job():
    jobs = get_open_jobs()
    flash('A job was not selected!')
    return index_temp.render(jobs = jobs)  

我们在尝试加载页面时收到以下错误:

jinja2.exceptions.UndefinedError: 'get_flashed_messages' is undefined

这里有什么区别? The answer in this question建议它们应该相同。但是,似乎我们无法访问flask方法。

1 个答案:

答案 0 :(得分:1)

我相信这里的区别在于flask.get_flashed_messages的工作方式。 该网页https://flask.palletsprojects.com/en/1.1.x/templating/解释了jinja2上下文变量的范围:

Jinja上下文行为:

这些变量被添加到变量的上下文中,它们不是全局变量。区别在于,默认情况下,这些不会显示在导入模板的上下文中。 部分原因是出于性能方面的考虑,部分原因是 保持明确。

在将烧瓶的render_templatejinja2.render进行比较时(在您所引用的问题链接中),这是与众不同的地方:

def render_template(template_name_or_list, **context):
    ctx = _app_ctx_stack.top
    ctx.app.update_template_context(context)
    return _render(ctx.app.jinja_env.get_or_select_template(template_name_or_list),
                   context, ctx.app)

def _render(template, context, app):   
    before_render_template.send(app, template=template, context=context)
    rv = template.render(context)
    template_rendered.send(app, template=template, context=context)
    return rv

通过直接调用render,您会丢失应用程序上下文更新调用,该调用将注入模板上下文处理器需要使模板可用的功能(在这种情况下,例如get_flashed_messages)的所有信息。 / p>