【问题标题】:flask form.validate_on_submit() fails using wtformsflask form.validate_on_submit() 使用 wtforms 失败
【发布时间】:2015-04-22 07:43:17
【问题描述】:

使用@dirn 的建议,验证错误不再显示,但它似乎仍然失败,因为 root() 函数中的 print 语句既没有显示/运行,也没有新的 form.errors 显示。

应用代码:

#!/usr/bin/env python

import cherrypy
import os
from flask import Flask, render_template, redirect, url_for, session, request, flash, abort, Markup
from flask.ext.bootstrap import Bootstrap
from sybload import funcs, forms

app = Flask(__name__)
app.debug = True
app.config['SECRET_KEY'] = os.urandom(24)
app.config['CSRF_ENABLED'] = True
bootstrap = Bootstrap(app)

dataserver_info = funcs.get_dataserver_info()
dataservers = funcs.get_dataservers(dataserver_info)

@app.route('/', methods=['GET', 'POST'])
def root():
    session.clear()
    form = forms.DataServersForm()
    form.dataserver.choices = zip(dataservers, dataservers)
    if form.validate_on_submit():
        session['dataserver'] = form.dataserver.data
        # print statement below never runs
        print session['dataserver'], form.dataserver.data
        return redirect(url_for('login'))
    return render_template('root.html', title='Sybase Load App', form=form)

def run_server():
    cherrypy.tree.graft(app, '/')
    cherrypy.config.update({
        'log.access_file': 'logs/access.log',
        'log.error_file': 'logs/errors.log',
        'engine.autoreload_on': True,
        'log.screen': True,
        'server.socket_host': '0.0.0.0',
        'server.socket_port': 5000,
        'tools.sessions.on': True,
        'tools.sessions.secure': True,
        'tools.sessions.httponly': True
    })
    cherrypy.engine.start()
    cherrypy.engine.block()

if __name__ == '__main__':
    run_server()

模板(jinja2):

    {% block body %}
    <form method='post' action='{{ url_for('login') }}'>
        {{ form.hidden_tag() }}

        {{ form.dataserver.label }}<br>
        {{ form.dataserver }}<br><br>

        {{ form.submit }}
    </form>
    <!-- Below never displays -->
    {% if form.errors %}
        failed validation
    {% endif %}
    {% endblock %}

表格:

from flask.ext.wtf import Form
from wtforms import StringField, PasswordField, SelectField, SelectMultipleField, SubmitField, BooleanField
from wtforms.validators import Required
import funcs

class DataServersForm(Form):
    dataserver = SelectField('Dataservers', validators=[Required()])
    submit = SubmitField('Submit')

【问题讨论】:

  • 您的代码示例显示您使用validate 方法而不是validate_on_submit
  • 您的表单发布到的网址也不是应用中显示的网址。

标签: python flask cherrypy wtforms


【解决方案1】:

每次有人访问'/' 时,您都会致电form.validate()。当请求是 GET 时,没有导致验证失败的表单数据。您只想在请求是 POST 时尝试验证表单。

一种方法是检查请求的方法。

if request.method == 'POST':
    if form.validate():
        session['dataserver'] = ds = form.dataserver.data
        return redirect(url_for('login'))
    else:
        flash('Failed validation')

另一种常见的方法是使用validate_on_submit。它处理检查 POST 以及验证表单。

if form.validate_on_submit():
    session['dataserver'] = ds = form.dataserver.data
    return redirect(url_for('login'))

在这里,您将失去发送'validation failed' 消息的能力。不过,这可能是可以接受的,因为您可以检查模板中的表单错误。

{% if form.errors %}
    failed validation
{% endif %}

更新

如果您想查看错误(可能不会),可以在模板中打印它们,而不是一般的“验证失败”消息。

{% if form.errors %}
    {{ form.errors }}
{% endif %}

【讨论】:

  • 在应用了你的两个建议之后,我相信还是有问题。 session['dataserver'] 从未正确设置。 @app.route('/', methods=['GET', 'POST']) def root(): session.clear() form = forms.DataServersForm() form.dataserver.choices = zip(dataservers, dataservers) if form.validate_on_submit(): session['dataserver'] = form.dataserver.data print session['dataserver'], form.dataserver.data return redirect(url_for('login')) return render_template('root.html', title='Sybase Load App', form=form)
  • 代码在 cmets 中效果不佳,请更新您的问题。
  • 您是否尝试过检查 form.errors 以查看表单是否无效?
  • 是的。 form.validate_on_submit() 之前的 form.errors 会产生一个空字典,而如果它位于“if form.validate_on_submit():”块内,它甚至永远不会运行(例如打印 form.errors)。
  • 如果表单验证失败,if 中的任何内容都不会发生。您需要(外部)if 之后检查它。这样做的一个地方就是我在答案中提到的模板。
【解决方案2】:

在我的情况下,同样的问题是缺少 CSRF 令牌。

【讨论】:

  • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-05
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
  • 2013-11-15
  • 2023-03-24
相关资源
最近更新 更多