扩展Flask-WTF继承了WTFforms,使用它能够在flask中更方便的使用WTForms。Flask-WTF将表单数据解析、CSRF保护、文件上传等功能与Flask集成。html
激活pipenv环境python
看下环境中安装了什么shell
pipenv install flask-wtf,安装flask-wtfflask
装完了后:app
flask-wtf默认为每一个表单启用CSRF保护,它为咱们自动生成和验证CSRF令牌。默认状况下,fflask-wtf使用程序秘钥来对CSRF令牌进行签名(token),因此咱们须要为程序设置秘钥:ui
app.secret_key = ‘secret string’spa
使用WTForms建立表单时,表单由python类表示,这个类继承从STForms导入的Form类。一个表单由若干个输入字段组成,这些字段分别用表单类的类属性来表示(字段即field,能够简单理解为表单内的输入框、按钮等部件),下面定义了一个LoginForm类,最终会生成像以前定义的HTML表单:命令行
from wtforms import Form, StringField, PasswordField, BooleanField, SubmitField from wfforms.validators import DataRequired, Length class LoginForm(Form): username = StringField('Username', validators=[DataRequired()]) password = PasswordField('Password', validators=[DataRequired(), Length(8,128)]) remember = BooleanField('Remember me') submit = SubmitField('Log in')
每一个字段属性经过实例化WTForms提供的字段类来表示。字段属性的名称将做为对应HTML<input>元素的name属性及id属性值。code
字段属性名称大小写敏感,不能如下划线或validate开头。orm
这里的LoginForm表单类中定义了四个字段:文本字段StringField、密码字段Pawword-Field、勾选框字段BooleanField和提交按钮字段SubmitField。字段类从wtforms包导入,有些字段最终生成的HTML代码相同,不过WTForms会在表单提交后根据表单类中字段的类型对数据进行处理,转换成对应的python类型,以便在python脚本中对数据进行处理。
经常使用的WTForms字段以下表:
经过实例化字段类时传入的参数,咱们能够对字段进行设置,字段类构造方法接受的经常使用参数以下表:
在WTForms中,验证器(validator)是一系列用于验证字段数据的类,咱们在实例化字段类时使用validators关键字来指定附加的验证器列表。验证器从wtforms.validators模块中导入,经常使用的验证器,以下表:
在实例化验证类时,message参数用来传入自定义错误消息,若是有设置则使用内置的英文错误消息
validators参数接收一个可调用对象组成的列表。内置的验证器经过实现了__call__()方法的类表示,因此咱们须要在验证器后添加括号。
在name和password字段里,咱们都是用了DataRequired验证器,用来验证输入的数据是否有效。另外,password字段里还添加了一个Length验证器,用来验证输入的数据长度是否在给定的范围内。验证器的第一个参数通常为错误提示消息,咱们可使用message关键字传递参数,经过传入自定义错误信息来覆盖内置消息,好比:
name = StringField(‘Your Name’, validators=[DataRequired(message=u’名字不能为空’)])
当使用Flask-WTF定义表单时,咱们仍然使用WTForms提供的字段类和验证器,建立的方式也彻底相同,只不过表单类要继承Flask-WTF提供的FlaskForm类。FlaskForm类继承自Form类,进行了一些设置,并附加了写辅助方法,以便与Flask集成。
咱们建立一个forms.py文件(form/forms.py),用来存储各类表单类。
下面例子是继承FlaskForm类的LoginForm表单:
from flask_wtf import FlaskForm from wtforms import StringField, PasswordField, BooleanField, SubmitField from wtforms.validators import DataRequired, Length class LoginForm(FlaskForm): username = StringField('Username', validators=[DataRequired()]) password = PasswordField('Password', validators=[DataRequired(), Length(8, 128)]) remember = BooleanField('Remember me') submit = SubmitField('Log in')
配置键WTF_CSRF_ENABLED用来设置是否开启CSRF保护,默认为True。Flask-WTF会自动在实例化表单时添加一个包含CSRF令牌值的隐藏字段,字段名为csrf_token。
以咱们使用WTForms建立的LoginForm为例,实例化表单类,而后将实例属性转换成字符串或直接调用就能够获取表单字段对应的HTML代码(须要在虚拟环境激活上下文):
>>> form = LoginForm()
>>> form.username()
u'<input id="username" name="username" required type="text" value="">'
>>> form.submit()
u'<input id="submit" name="submit" type="submit" value="Log in">'
>>> form.password()
u'<input id="password" name="password" required type="password" value="">'
>>> form.remember()
u'<input id="remember" name="remember" type="checkbox" value="y">'
字段的<label>元素的HTML代码则能够经过”form.字段名.label”的形式获取:
>>> form.username.label()
u'<label for="username">Username</label>'
>>> form.submit.label()
u'<label for="submit">Log in</label>'
在虚拟环境下,须要激活程序上下文(app_context)和请求上下文(request_context),才能实例化运行上面的程序,激活上下文能够经过如下方式:
一、 pipenv shell 激活虚拟环境
二、到appForm.py所在目录:D:\flask\FLASK_PRACTICE
三、运行python进入python命令行模式
四、激活程序上下文:
>>> from appForm import app
>>> from flask import current_app
>>> app_ctx=app.app_context()
>>> app_ctx.push()
>>> current_app.name
'appForm'
五、激活请求上下文:
>>> from appForm import app
>>> from flask import request
>>> app_re=app.test_request_context('/html')
>>> app_re.push()
>>> request.method
'GET'
六、把LoginForm()类定义运行一下
>>> from flask_wtf import FlaskForm
>>> from wtforms import StringField, PasswordField, BooleanField, SubmitField
>>> from wtforms.validators import DataRequired, Length
>>>
>>> class LoginForm(FlaskForm):
... username = StringField('Username', validators=[DataRequired()])
... password = PasswordField('Password', validators=[DataRequired(), Length(8, 128)])
... remember = BooleanField('Remember me')
... submit = SubmitField('Log in')
以后就能够实例化这个类,作其余的事情了
在建立HTML表单时,咱们常常会须要使用HTML<input>元素的其余属性来对字段进行设置。好比class属性设置对应的CSS类为字段添加样式;添加placeholder属性设置占位文本。默认状况下WForms输出的字段HTML代码只会包含id和name属性,属性值均为表单类中对应的字段属性名称。若是要添加额外的属性,一般有两种方法。
使用render_kw属性
好比下面为username字段使用render_kw设置了placeholder HTML属性:
username = StringField(‘Username’ render_kw={‘placeholder’: ‘Your Username’})
这个字段被调用后输出的HTML代码是:
<input type=”text” id=”username” name=”username” placeholder=”Your Username”>
调用字段时传入
在调用字段属性时,经过添加括号使用关键字参数的形式也能够传入字段额外的HTML属性:
>>> form.username()
u'<input id="username" name="username" required type="text" value="">'
>>> form.username(style='width:200px;',class_='bar')
u'<input class="bar" id="username" name="username" required style="width:200px;" type="text" value="">'
class是pyhton的保留字,咱们使用class_来代替class,渲染后的<input>会得到正确的classl属性,在模板中调用时则能够直接使用class。
经过上面的方法也能够修改id和name属性,但表单被提交后,WTForms须要经过name属性来获取对应的数据,因此不能修改name属性值。