在了解了 Flask Bootstrap 基本框架之后,我们来了解一下 Flask 框架的 表单( form ),以帮助我们创建交互式的 Web 应用,最后会有个提交个人信息的例子。 Flask-WTF 是 Flask 框架的一个扩展,用来做表单的交互,是对 WTForms 的集成,默认支持 CSRF 安全签名,并且继承文件上传功能。 安装使用 pip 安装 pip install Flask-WTF 验证 >>> from flask_wtf import FlaskForm >>> 小试牛刀创建表单类Flask-WTF 能将 WTForms 集成到 Flask 应用中,创建一个 from flask_wtf import FlaskForm from wtforms import StringField from wtforms.validators import DataRequired
class MyForm(FlaskForm): name = StringField('name', validators=[DataRequired()]) MyForm 是自定义的类,继承自 FlaskForm,其中定义了一个字段 name,标题是 name, 且设置为非空。 表单模板接下来创建一个表单模板 <form method="POST" action="/"> {{ form.csrf_token }} {{ form.name.label }} {{ form.name(size=20) }} <input type="submit" value="Go"> </form> 其中 密钥串与多种定义方式,为了方便,这里将密钥串定义在应用上: app.secret_key = 'abc'
之后则是对字段 定义视图函数视图函数首先需要将表单渲染出来,另外要对表单的提交作验证,当然视图函数与提交验证函数也可不是同一个: @app.route('/', methods=('GET', 'POST')) def submit(): form = MyForm() if form.validate_on_submit(): return redirect('/success') return render_template('submit.html', form=form) 提交表单一般都是 POST 方法,所以要确保视图函数支持 POST 视图函数中实例化一个 MyForm,值得注意的时,FlaskForm 示例化时会使用 request 中的 form 来初始化,所以在下面才可以直接来校验表单 validate_on_submit 方法是 is_submitted 和 validate 的联合校验,后面会详述 如果验证通过将跳转到 运行在主代码 if __name__ == '__main__': app.run(debug=True) 然后运行,如果一起正常,访问 表单FlaskForm 是 WTForms Form 的子类,可以用来定一个表单,定义表单中的字段,验证方式等,作为一个 Flask 和 Html 之间的一个数据载体。 另外 FlaskForm 集成了 CSRF 校验,方便编写程序的同时,提高访问安全性。定义 Form 对象时不用明确声明 CSRF 字段,只需要在表单模板中填写 FlaskForm 实例化参数中有个 formdata 参数,用来设定 Form 中字段的值,在视图函数中,可以不提供 formdata,会将 request.form 或者 request.files 中获取,作为 formdata 参数,这就是视图函数中实例化 Form 时,不带任何参数,在后面还能方法 Form 对象内容的原因。 字段及验证FlaskForm 从 0.9.0 版本开始,不再从 WTForms 中导入任何东西,所以大部分字段和校验方法都直接引用自 WTForms,如: from wtforms import StringField, IntergreField, validators
例如定义一个 MyForm 表单类: class MyForm(FlaskForm): name = StringField(label='姓名', validators=[InputRequired()]) city = StringField('城市', validators=[validators.Length(min=4, max=25, message='输入的长度不符合要求')]) birthday = DateField(label='生日', format="%Y-%m-%d", validators=[DataRequired('日期格式不正确')]) gender = RadioField(label='性别', choices=[(1, 'male'), (2, 'female')]) interest = SelectMultipleField(label='兴趣', choices=[(1, 'Football'), (2, 'Movies'), (3, 'Reading')]) 如果字段值验证失败,会将错误信息存放在字段的 要完整的在模板中定义字段以及错误信息,是件乏味的事情,这里通过一个自定义的模板宏来完成: {% macro render_field(field) %} <dt>{{ field.label }}: <dd>{{ field(**kwargs)|safe }} {% if field.errors %} <ul class=errors> {% for error in field.errors %} <li>{{ error }}</li> {% endfor %} </ul> {% endif %} </dd> {% endmacro %} 文件上传上传文件,是表单应用必不可少的,可以通过 FileField 字段来设置,因为需要视图函数对上传的文件进行处理,所以这里单独作说明 定义一个有上传文件字段的表单类: from flask_wtf.file import FileField
class PhotoForm(FlaskForm): photo = FileField('上传照片') 视图函数定义为: @app.route('/upload', methods=['GET', 'POST']) def upload(): form = PhotoForm() filepath = None if form.validate_on_submit(): filename = secure_filename(form.photo.data.filename) file = form.photo.data filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename) file.save( filepath ) else: filename = None return render_template('photo.html', form=form, filename= filename) 在通过验证之后,用方法 之后拿到上传文件的数据,这是已经经过 Flask 转化的 File 对象,可以直接调用 save 方法存储上传的文件。
app.config['UPLOAD_FOLDER'] = './upload' 最后新建一个模板文件 upload.html: <form action="/upload" method="post" enctype="multipart/form-data"> {{ form.csrf_token() }} {{ form.photo() }} <input type="submit" value="提交"> </form> 注意模板中 Bootstrap虽然 FlaskForm 使用起来已经很方便了,但是还是有很多需要重复编写的地方,以及展示效果不够美观的问题,借助 之前对 首先在模板中导入 bootstrap 的 Form 相关宏: {% from 'bootstrap/form.html' import render_form, render_form_row, render_field %}
{{ render_form(form) }}
{{ render_field(form.name) }}
模板代码如下: {% from 'bootstrap/form.html' import render_form, render_form_row, render_field %} {{ bootstrap.load_css() }} <h1> render_form </h1> {{ render_form(form) }}
<h1>render_form_row</h1> <form method="post" > {{ render_form_row([form.name, form.city]) }} {{ render_form_row([form.gender, form.birthday]) }} {{ render_form_row([form.interest]) }} </form>
<h1>render_field</h1> <form method="post" > {{ render_field(form.name) }} {{ render_field(form.gender) }} {{ render_field(form.interest) }} </form> 先导入表单相关的宏,然后加入 Bootstrap 的样式,之后是各个宏的使用 总结本节课程简单介绍了 Flask 中表单的处理方式和方法,包括 FlaskForm,WTForms和一些常用的字段,最后说明了 Bootstrap-flask 对表单的支持,以便是 Web 开发更高效。
参考
系列文章 第0-40天:从0学习Python 0-40合集 |
|