尽管request.form能获取POST请求中的提交的表单数据,也就是说Flask的请求对象提供的信息足够用于处理web表单,但是任务单调,比如生成表单的HTML代码和验证提交的表单数据等等。
这时候Flask-WTF应运而生,Flask-WTF及其依赖安装:
pip install flask-wtf
(venv) C:\Users\Geek Lee\Geek-Lee.github.io>pip install flask-wtf
Collecting flask-wtf
Collecting WTForms (from flask-wtf)
...
Installing collected packages: WTForms, flask-wtf
Successfully installed WTForms-2.1 flask-wtf-0.12
注意安装了 WTForms, flask-wtf两个包。
from flask import Flask, render_template
from flask_script import Manager
from flask_bootstrap import Bootstrap
from flask_moment import Moment
from flask_wtf import Form ###Form基类是由Flask-WTF扩展定义,应从flask_wtf引入
from wtforms import StringField, SubmitField ###字段和验证函数直接从wtforms直接引入
from wtforms.validators import Required ###
app = Flask(__name__)
app.config['SECRET_KEY'] = 'hard to guess string' ###
###为了实现CSRF保护,Flask-WTF需要程序设置一个密钥。
###app.config字典可用来存储框架,扩展,和程序本身的配置变量。
###SECRET_KEY配置变量是通用密钥,可在Flask和多个第三方扩展中使用。
manager = Manager(app)
bootstrap = Bootstrap(app)
moment = Moment(app)
class NameForm(Form): ###定义表单类
name = StringField('What is your name?', validators=[Required()])
submit = SubmitField('Submit')
@app.route('/', methods=['GET', 'POST'])#加入POST方法
def index():
name = None
form = NameForm() ###把表单类传入变量form
if form.validate_on_submit():
name = form.name.data
form.name.data = ''
return render_template('index.html', form=form, name=name)
###把表单对象form传入模板的变量form
@app.errorhandler(404)
def page_not_found(e):
return render_template('404.html'),404
@app.errorhandler(500)
def internal_server_error(e):
return render_template('500.html'),500
if __name__ == '__main__':
manager.run()
流程
用户第一次输入‘/’,服务器会收到一个没有表单数据的GET请求,所以validate_on_submit()将返回False,if语句跳过,返回一个值为None的name变量和表单对象的模板。
第二次时,用户提交了一个表单,服务器收到了一个包含数据的POST请求,validate_on_submit()将调用name字段上附属的Required()验证函数。如果通过,执行if语句,name = form.name.data(表单数据传入name变量) form.name.data = ”(表单数据清空)。最后返回一个带有值的name变量的模板。
返回的模板
{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
###导入文件bootstrap/wtf.html定义了一个使用Bootstrap渲染Flask-WTF表单对象的辅助函数。
{% block title %}GeekLee{% endblock %}
{% block page_content %}
<div class="page-header">
<h1>Hello, {% if name %}{{ name }}{% else %}Stranger{% endif %}!</h1>
</div>
{{ wtf.quick_form(form) }}
###wtf.quick_form()函数的参数为Flask-WTF对象,使用Bootstrap默认的样式渲染传入的表单
{% endblock %}