Python - Flask:如何在渲染之前分配变量?

Posted

技术标签:

【中文标题】Python - Flask:如何在渲染之前分配变量?【英文标题】:Python - Flask: How do i assign variables before rendering? 【发布时间】:2018-02-27 20:04:50 【问题描述】:

我一直在寻找在渲染之前分配变量的方法,但没有找到任何东西。

php 中,我可以在渲染模板之前分别在任何函数中这样做,我只需要 $tpl 对象:

$tpl->assign('a', $a);
$tpl->output(...);

因此处理从@app.route返回输出或使用Flask将变量分配给模板等过程非常困难

例如,如果用户启用了 javascript,我想处理消息报告(返回或分配变量),如果用户执行 ajax 请求,它返回 json 字符串,如果没有,则将变量分配给模板。

这是我的代码

@admin.route('/login')
def login():
    ...
    if form.validate_on_submit():
        return helper.msg_report(...)

    return render_template('login.pug', **locals())

def msg_report(ajax, type, msg):
    if not ajax:
        # need to assign msg variable to template here
    else:
        res = dict()
        res['error'] = dict()
        res['error']['message'] = mark_msg('error', msg)
        return json.dumps(res)

【问题讨论】:

您可以在模板代码中使用分支。我认为没有充分的理由提前分配值。 @OluwafemiSule 很好的理由是你可以分离代码,在这种情况下,一个可重用的代码来处理错误消息。使用 PHP,我只需要几行代码,使用 Python + Flask,我不知道该怎么做,它也破坏了面向对象的设计——没有模板对象!我已经用 Flask-Admin、Wtforms 等 Flask 测试了许多表单视图......他们都没有用 ajax 完成一项工作。 Jinja 很健壮。您可以选择性地include(有一个包含指令) 可重复使用的错误模板。有一个模板对象,它只是抽象出来的,因为你真的不需要处理它。 @OluwafemiSule 那么我如何访问该模板对象?我知道模板引擎是如何工作的,但是让我们尝试解决我的情况,ajax 表单验证它必须手动从代码返回结果,因为我没有看到 flask-* 支持的 ajax 东西 什么样的结果? 【参考方案1】:

在您的示例中,您分配给模板的变量是 **locals()

例如,假设您的模板中有一个名为text 的变量。您可以通过return render_template('login.pug', text="what you want") 分配它。

所以你只需要返回一个字典,比如result = msg_report(ajax, type, msg),然后是return render_template('login.pug', **result)

【讨论】:

我知道,但是还是需要在里面定义result变量,意思是写更多的代码,有什么办法自动生成变量或者赋值给模板对象?【参考方案2】:

您可以在msg_report 中回复回复。 当form.validate_on_submit 为真时,单独更新模板上下文将返回None。 IE。 不会向客户端返回任何响应。

from flask import jsonify, render_template

...

def msg_report(ajax, type, msg, **ctx): # pass variables needed by template here
    if not ajax:
        # update ctx before passing here
        ctx.update('error': msg)

        return render_template('login.pug', **ctx)

    rv = 
        'error': 
            'message':  mark_msg('error', msg)
        
    

    return jsonify(rv)

如果您仍想继续更新模板上下文,您可以使用:

from flask import current_app as app

ctx = 
    'error': msg


app.update_template_context(ctx)

【讨论】:

我收到了错误NameError: name 'render_template' is not defined 我必须通过的 ctx 是什么? msg_report 在其他文件中(helper.py) 我认为应该是locals()。你把它传递给helper.msg_report 被调用的地方 **local()login() 内部的所有局部变量,它们都将分配给模板对象。关于您的代码,render_template 将永远无法工作,因为它超出了@app.route('/') 你的意思是render_template 不起作用?在helpers.msg_report 中使用之前,您是否从flask 导入了render_template 函数? 对不起,我已经导入了render_template,但是仍然不能让它工作,因为模板需要我在路由文件中声明的form = LoginForm()才能工作,我不认为这是好的做法,render_template 永远不应该离开路由文件

以上是关于Python - Flask:如何在渲染之前分配变量?的主要内容,如果未能解决你的问题,请参考以下文章

网站后端_Python+Flask.0014.FLASK模版相关之使用JinJa2模版渲染?

你如何使用 Flask-Login 和自定义 Python 装饰器来分配用户权限?

Python Flask 从像 render_template 这样的变量渲染文本

在渲染模板中将变量从python(flask)传递给HTML?

Flask10 登录模块表单框架表单渲染表单验证bookie请求之前钩子g对象编写装饰器

Python Flask Jinja - 扩展模板时扩展/渲染模板