之前,学习使用request.form获取表单数据。但是有些任务重复单调,可以实现自动化管理,比如 :生成表单的HTML代码、验证提交的表单数据。
Flask-wtf是flask的一个扩展,可以把重复工作变得更简单。
一、安装flask-wtf和跨站请求伪造保护(CSRF)
# pyCharm Terminal #安装 pip install flask-wtf
# test.py app = Flask(__name__) app.config['SECRET_KEY'] = 'hard to guess string' #设置app的config字典
app的config字典用来存储框架、扩展和程序本身的配置变量。
二、使用flask-wtf
# test.py from flask_wtf import FlaskForm #引入FlaskForm类,作为自定义Form类的基类 from wtforms import StringField,SubmitField #StringField对应HTML中type="text"的<input>元素,SubmitField对应type='submit'的<input>元素 from wtforms.validators import Required #引入验证函数 class NameForm(FlaskForm): name = StringField('What is your name?',validators=[Required()]) submit = SubmitField('Submit')在这个示例中,NameForm表单有一个 名为name的文本字段(我感觉类似于Qt中的QLineEdit类)和一个名为submit的提交按钮(感觉类似于Qt中的QPushButton类)。字段(StringField和SubmitField)的构造函数的第一参数对应HTML的标号(用以显示的字)。
name = StringField('What is your name?',validators=[Required()])validators指定一个由验证函数组成的列表 。(验证函数,我感觉就是对用户输入的一种检查:排除非法输入)。
附:WTFForms支持的HTML标注字段
字段类型 说 明
StringField 文本字段
TextAreaField 多行文本字段
PasswordField 密码文本字段
HiddenField 隐藏文本字段
DateField 文本字段,值为 datetime.date 格式
DateTimeField 文本字段,值为 datetime.datetime 格式
IntegerField 文本字段,值为整数
DecimalField 文本字段,值为 decimal.Decimal
FloatField 文本字段,值为浮点数
BooleanField 复选框,值为 True 和 False
RadioField 一组单选框
SelectField 下拉列表
SelectMultipleField 下拉列表,可选择多个值
FileField 文件上传字段
SubmitField 表单提交按钮
FormField 把表单作为字段嵌入另一个表单
FieldList 一组指定类型的字段
附:WTForms 内建的验证函数
函数 说明
Email 验证电子邮件地址EqualTo 比较两个字段的值;常用于要求输入两次密码进行确认的情况
IPAddress 验证 IPv4 网络地址
Length 验证输入字符串的长度
NumberRange 验证输入的值在数字范围内
Optional 无输入值时跳过其他验证函数
Required 确保字段中有数据
Regexp 使用正则表达式验证输入值
URL 验证 URL
AnyOf 确保输入值在可选值列表中
NoneOf 确保输入值不在可选值列表中
三、把表单渲染成HTML
# index.html {% extends "base.html" %} {% block title %}Flasky{% endblock %} {% block navbar %} <div class="navbar navbar-inverse" role="navigation"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="/">Flasky</a> </div> <div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li><a href="/">Home</a></li> </ul> </div> </div> </div> {% endblock %} {% block content %} #正文block <div class="container"> <div class="page-header"> <h1>Hello, {{ name }}!</h1> #需要传入的变量{{ name }} </div> <form method="post"> #需要传入的变量form类 {{ form.hidden_tag() }} #调用form.hidden_tag()方法 {{ form.name.label }}{{ form.name() }} #同上 {{ form.submit() }} </form> </div> {% endblock %}
四、使用Bootstrap中的表单样式
# index.html {% import "bootstrap/wtf.html" as wtf %} #引入wtf.html中的定义,并起别名wtf(类比python模块) {% block content %} <div class="container"> <div class="page-header"> <h1>Hello, {{ name }}!</h1> </div> <form method="post"> {{ form.hidden_tag() }} {{ form.name.label }}{{ form.name() }} {{ form.submit() }} </form> {{ wtf.quick_form(form) }} #wtf.quick_form(form)使用默认的样式渲染form </div> {% endblock %}
五、提交表单整个工作流程(重点)
1、客户端输入URL,访问服务器。向服务器发出一个GET请求
2、服务器收到请求。进入视图函数(index())处理。
# tset.py @app.route("/",methods=['GET','POST']) def index(): name = None form = NameForm() if form.validate_on_submit(): #服务器收到没有表单数据的GET请求 ,因此form.validate_on_submit() == False name = form.name.data #不执行,跳过 form.name.data='' #不执行 ,跳过 return render_template('index.html',name=name,form=form) #把name,form变量传入模板,渲染,返回给客户端。
3、客户端收到并显示表单
4、用户输入并提交表单
5、服务器收到包含数据的POST请求
6、再进视图函数,validate_on_submit()函数调用验证函数(Required()),验证通过返回True,否则返回False.
# test.py @app.route("/",methods=['GET','POST']) def index(): name = None form = NameForm() if form.validate_on_submit(): #返回True name = form.name.data #执行 form.name.data='' #执行 return render_template('index.html',name=name,form=form) #把name,form变量传入模板,渲染,返回。
7、客户端最终效果