Flask-WTF 提供了对 WTForms 的集成, 从 0.9.0 版本开始,Flask-WTF 不再从 WTforms 中导入任何东西,你需要从 WTForms 导入字段。表单字段的定义需要去WTForms中参考:http://wtforms.readthedocs.io/en/latest/
默认情况下,Flask-WTF为避免CSRF攻击,需要程序设置一个密钥。
app = Flask(__name__)
app.config['SECRET_KEY'] = 'xcxxxx'
定义表达类:使用Flask-WTF,每个表达都由一个继承Form的类表示
from flask_wtf import Form
from wtforms import TextField, SubmitField
from wtforms.validators import DataRequired
class MyForm(Form):
name = StringField('name', validators=[DataRequired()])
submit = SubmitField('Submit')
模版中渲染
<form method="POST" action="/">
{{ form.csrf_token }}
{{ form.name.label }} {{ form.name(size=20) }}
</form>
或配合flaks-bootstarp直接生成
{% import "bootstarp/wtf.html" as wtf%}
{{ wtf.quick_form(form) }}
视图中验证表达
@app.route('/submit', methods=('GET', 'POST'))
def submit():
form = MyForm()
if form.validate_on_submit():
return redirect('/success')
return render_template('submit.html', form=form)
上传文件
定义表单类
from flask_wtf.file import FileField, FileAllowed, FileRequired
class MyForm(Form):
name = StringField('name', validators=[DataRequired()])
photo = FileField('Your photo', validators=[FileRequired(), FileAllowed(['jpg', 'png'], 'Image Only')])
submit = SubmitField('Submit')
试图函数中处理
from flask import request
from werkzeug.utils import secure_filename
@main.route('/myform', methods=['GET', 'POST'])
def myform():
form = MyForm()
if form.validate_on_submit():
uploadFile = request.files['photo'] # 获取上传文件句柄
uploadFile.save('/tmp/%s' %secure_filename(uploadFile.filename)) # secure_filenamed检测并过滤用户的输入
return redirect('/')
return render_template('myform.html', form=form)
模版中注意
注解
请记得设置 HTML 表单的 enctype 为 multipart/form-data , 即:
<form action="/upload/" method="POST" enctype="multipart/form-data">
....
</form>
wtforms SelectField 动态添加option项
很多情况下我们使用<select>
表单的时候会动态从数据库中加载值, 修改实例化form类对象的属性;
例如:在用户注册页面可能需要选择角色
Form类
class AddUserForm(Form):
name = StringField('Username', validators=[DataRequired()])
role_id = SelectField('role', choices=[], coerce=int)
submit = SubmitField(u'提交')
Views
form = AddUserForm()
form.role_id.choices += [(r.id, r.name) for r in Role.query.order_by('name').all() ]