Python Flask应用程序提交目标="_“空白”;仅在wtforms验证后生成表单

Python Flask应用程序提交目标="_“空白”;仅在wtforms验证后生成表单,python,flask,wtforms,Python,Flask,Wtforms,在我的Flask应用程序中,我使用wtforms和jinja模板生成了一个表单。如果验证通过,我希望在新选项卡中重定向,否则我希望保持在同一页面上并显示错误。但是,如果我在表单中设置target=“\u blank”,它会在未通过验证的情况下打开一个新选项卡,并在那里显示错误。删除target=“\u blank”不会打开新选项卡。有没有一种方法可以在不重写js中的整个验证的情况下实现这一点?谢谢 代码: index.html: {% from "_formhelpers.html" impor

在我的Flask应用程序中,我使用
wtforms
jinja
模板生成了一个表单。如果验证通过,我希望在新选项卡中重定向,否则我希望保持在同一页面上并显示错误。但是,如果我在表单中设置
target=“\u blank”
,它会在未通过验证的情况下打开一个新选项卡,并在那里显示错误。删除
target=“\u blank”
不会打开新选项卡。有没有一种方法可以在不重写js中的整个验证的情况下实现这一点?谢谢

代码:

index.html:

{% from "_formhelpers.html" import render_field %}
<form method=post action="/" target="_blank">
  <dl>
    {{ render_field(form.field1) }}
    {{ render_field(form.field2) }}
  </dl>
  <p><input type=submit value=Submit>
</form>
{%来自“\u formhelpers.html”导入呈现\u字段%}
{{render_field(form.field1)}
{{render_field(form.field2)}

\u formhelpers.html(不太相关,但为了完整):

{%macro render_field(field)%}
{{field.label}
{{字段(**kwargs)|安全}
{%if field.errors%}

{%字段中有错误。错误%}
  • {{error}}
  • {%endfor%} {%endif%} {%endmacro%}
    主要问题 您必须传递
    表单
    对象以及表示表单字段的变量,即
    field1
    field2

    细节 上述内容意味着您需要更改:

    返回重定向('/my\u redirect\u uri')

    返回重定向('/my\u redirect\u uri',form=form,field1=field1,field2=field2)

    这也意味着您必须调整查看方法:

    @app.route('/', methods=['POST'])
    def sub():
        form = SubmitForm(request.form)
        if request.method == 'POST' and form.validate():
            # great success
            field1 = form.field1.data
            field2 = form.field2.data
            return redirect('/my_redirect_uri', form=form, field1=field1, field2=field2)
        return render_template('index.html', form=form)
    
    现在,您的程序有一些改进:

    • 无代码原则:
    if request.method==“POST”和form.validate():
    替换为
    if form.validate\u on_submit():
    (保存一条指令)

    • 使用:
    因为在您的程序的未来版本和重新编辑中,当使用
    url\u For()
    生成url时,对路由名称所做的任何更改都将自动可用。您可以在
    返回重定向('/my\u redirect\u uri')
    中使用它(您可以查看我提供的链接以了解更多信息)

    • 使用会话:
    会话将使您的应用程序“能够记住”正在发送的表单数据。在您的示例中,您可以通过以下方式使用会话:

    session['field1'] = form.field1.data
    session['field2'] = form.field2.data
    
    app.config['SECRET_KEY'] = 'some secret phrase of your own'
    
    这意味着,例如,上述行:

    return redirect('/my_redirect_uri', form=form, field1=field1, field2=field2)
    
    必须更改为:

    return redirect('my_redirect_uri', form=form, session.get('field1'), session.get('field2'))
    
    请注意,如果要实现会话,则需要设置密钥,因为它们存储在客户端,因此需要对它们进行保护(Flask的原理是加密)。这意味着您必须以以下方式配置应用程序:

    session['field1'] = form.field1.data
    session['field2'] = form.field2.data
    
    app.config['SECRET_KEY'] = 'some secret phrase of your own'
    
    实际上,问题与您打开的浏览器选项卡无关。整个问题源于
    redirect()
    语句

    关于为什么使用会话很好的更多详细信息?检查下一个最后部分:

    关于重定向的一句话: POST请求由
    重定向处理
    ,因此当POST请求结束时,您将失去对表单数据的访问

    redirect语句只是一个响应,当收到该响应时,浏览器会发出GET请求。该机制主要用于以下(及类似)情况:


    如果尝试刷新提交表单数据的同一浏览器窗口,浏览器将提示您一个弹出窗口,以确认是否要(再次)发送数据,因为根据设计,浏览器会记住上次执行的请求。当然,这对应用程序的用户来说是不好的。在这方面,我们需要会议。这对重定向到的浏览器选项卡也很有帮助。

    我想你是对的。您需要编写一个简单的控制器来验证Ajax请求,然后可以打开新选项卡,