如何重写此Flask视图函数以遵循post / redirect / get模式?

时间:2017-01-08 14:19:23

标签: python flask

我有一个小型日志浏览器。它根据用户的输入检索并显示以前记录的记录列表。它不会更新任何内容。

代码非常简单,工作正常。这是一个简化版本:

@app.route('/log', methods=['GET', 'POST'])
def log():
    form = LogForm()
    if form.validate_on_submit():
        args = parse(form)
        return render_template('log.html', form=form, log=getlog(*args))
    return render_template('log.html', form=form)

但是它不遵循post / redirect / get模式,我想解决这个问题。

我应该在哪里存储发布的数据(即args)之间的帖子和获取?什么是标准或推荐的方法?我应该设置一个cookie吗?我应该使用flask.session对象,在那里创建一个缓存吗?你能指点我正确的方向吗?大部分时间我都在写后端...

更新:

我发布了生成的代码。

@app.route('/log', methods=['POST'])
def log_post():
    form = LogForm()
    if form.validate_on_submit():
        session['logformdata'] = form.data
        return redirect(url_for('log'))
    # either flash errors here or display them in the template
    return render_template('log.html', form=form)

@app.route('/log', methods=['GET'])
def log():
    try:
        formdata = session.pop('logformdata')
    except KeyError:
        return render_template('log.html', form=LogForm())

    args = parse(formdata)
    log = getlog(args)
    return render_template('log.html', form=LogForm(data=formdata), log=log)

2 个答案:

答案 0 :(得分:5)

因此,最终post/redirect/get pattern可以防止多次提交表单数据。由于您的POST实际上没有对任何数据库进行更改,因此您使用的方法似乎很好。通常在模式中POST对底层数据结构进行更改(例如UPDATE / INSERT / DELETE),然后在重定向上查询更新的数据(SELECT),因此通常您不需要“存储”任何内容在重定向和获取之间。

尽管如此,我的方法是使用Flask session对象,这是Flask为您管理的Cookie。你可以这样做:

@app.route('/log', methods=['GET', 'POST'])
def log():
    form = LogForm()
    if form.validate_on_submit():
        args = parse(form)
        session['log'] = getlog(*args)
        return redirect(url_for('log'))
    saved = session.pop('log', None)
    return render_template('log.html', form=form, log=saved)

此外,要使用会话,您必须在应用程序配置中设置secret_key

Flask Session API

更新2016年1月9日

Per ThiefMaster的评论,重新安排逻辑顺序,允许使用WTForms验证方法提交无效表单,因此无效的表单提交不会丢失。

答案 1 :(得分:1)

在Flask中进行P / R / G的常用方法是:

@app.route('/log', methods=('GET', 'POST'))
def log():
    form = LogForm()
    if form.validate_on_submit():
        # process the form data
        # you can flash() a message here or add something to the session
        return redirect(url_for('log'))
    # this code is reached when the form was not submitted or failed to validate
    # if you add something to the session in case of successful submission, try
    # popping it here and pass it to the template
    return render_template('log.html', form=form)

保留在POSTed页面上,以防表单无法验证WTForms预填充用户输入数据的字段,并且您可以在表单呈现期间显示每个字段的错误(通常人们会编写一些Jinja宏来呈现WTForm容易)