flask form.validate_on_submit() 使用 wtforms 失败
flask form.validate_on_submit() fails using wtforms
使用@dirn 的建议,验证错误不再显示,但它似乎仍然失败,因为 root() 函数中的打印语句 displays/runs 和新的 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')
每当有人访问 '/'
时,您都会致电 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 %}
更新
如果您想查看错误(您可能不会),您可以在模板中打印它们而不是通用的 "failed validation" 消息。
{% if form.errors %}
{{ form.errors }}
{% endif %}
在我的案例中,同样的问题是缺少 CSRF 令牌。
使用@dirn 的建议,验证错误不再显示,但它似乎仍然失败,因为 root() 函数中的打印语句 displays/runs 和新的 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')
每当有人访问 '/'
时,您都会致电 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 %}
更新
如果您想查看错误(您可能不会),您可以在模板中打印它们而不是通用的 "failed validation" 消息。
{% if form.errors %}
{{ form.errors }}
{% endif %}
在我的案例中,同样的问题是缺少 CSRF 令牌。