在 Jinaj2.Template.render() 中访问烧瓶方法
Accessing flask methods in Jinaj2.Template.render()
假设我们有这样一个烧瓶模板:
{% 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 的模板 class 函数 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
这里有什么区别? 建议它们应该相同。然而,我们似乎无法访问 flask
方法。
我认为这里的区别在于 flask.get_flashed_messages
的工作方式。
此网页 https://flask.palletsprojects.com/en/1.1.x/templating/ 解释了 jinja2 上下文变量的范围:
The Jinja Context Behavior:
These variables are added to the context of variables, they are not global variables. The difference is that by default these will not show up in the context of imported templates.
This is partially caused by performance considerations, partially to
keep things explicit.
这就是 flask 的 render_template
与 jinja2.render
相比的不同之处(来自您提到的问题 link):
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
)可用于模板所需的所有信息.
假设我们有这样一个烧瓶模板:
{% 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 的模板 class 函数 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
这里有什么区别? flask
方法。
我认为这里的区别在于 flask.get_flashed_messages
的工作方式。
此网页 https://flask.palletsprojects.com/en/1.1.x/templating/ 解释了 jinja2 上下文变量的范围:
The Jinja Context Behavior:
These variables are added to the context of variables, they are not global variables. The difference is that by default these will not show up in the context of imported templates. This is partially caused by performance considerations, partially to keep things explicit.
这就是 flask 的 render_template
与 jinja2.render
相比的不同之处(来自您提到的问题 link):
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
)可用于模板所需的所有信息.