【问题标题】:Python - Flask: How do i assign variables before rendering?Python - Flask:如何在渲染之前分配变量?
【发布时间】: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 东西
  • 什么样的结果?

标签: python variables flask template-engine


【解决方案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 永远不应该离开路由文件
猜你喜欢
  • 1970-01-01
  • 2023-03-27
  • 2015-05-31
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
  • 2022-01-15
  • 2016-11-29
  • 2016-01-28
相关资源
最近更新 更多