文章目录
使用flask处理表单
传统的前端通用表单,需要前后端共同完成操作,前端需要使用form
标签来定义表单,而后端则需要使用request.form
来获取post
请求中的表单数据:
# 判断请求方式
if request.method == 'POST':
# 获取表单中name为username的文本域提交的数据
name = request.form.get('username')
# 获取表单中name为password的文本域提交的数据
password = request.form.get('password')
return name+" "+password
- 上述的方法既没有为表单提供保护措施,也不利于前后端分离的改进需求,固我们引入第三方扩展包:
flask-wtf
与wtforms
,来实现由后端单独完成的表单操作:
wtforms
安装:pip install wtforms
flask-wtf
安装:pip install Flask-WTF
或pip install flask-wtf
wtforms
依照功能类别来说wtforms
分别由以下几个类别:
Forms
: 主要用于表单验证、字段定义、HTML
生成,并把各种验证流程聚集在一起进行验证。Fields
: 包含各种类型的字段,主要负责渲染(生成HTML
文本域)和数据转换。Validator
:主要用于验证用户输入的数据的合法性。比如Length
验证器可以用于验证输入数据的长度。Widgets
:html
插件,允许使用者在字段中通过该字典自定义html
小部件。Meta
:用于使用者自定义wtforms
功能(配置),例如csrf
功能开启。Extensions
:丰富的扩展库,可以与其他框架结合使用,例如django
。
Flask-WTF
其实是对wtforms
的简单集成,也能通过添加动态token
令牌的方式,为所有Form
表单提供免受CSRF
(Cross-site request forgery
——跨站请求伪造)攻击的技术支持
我们可以采用以下方法来启用CSRF
保护:
- 定义配置文件,再将配置文件中的配置语句通过
app.config.from_object
(<配置对象>)或app.config.from_pyfile
(<‘配置文件名’>)导入到flask
对象app
中,这个配置对象可以是配置模块也可以是配置类:
# config.py
CSRF_ENABLED = TRUE # 用于开启CSRF保护,但默认状态下都是开启的
SECRET_KEY = 'X1X2X3X4X5' # 用于生成动态令牌的秘钥
- 其中
SECRET_KEY
用于建立加密令牌token
,在我们编写程序时可以尽量定义的复杂一些;
from flask import Flask
from flask_wtf.csrf import CSRFProtect # 导入CSRFProtect模块
import config # 导入配置文件
app = Flask(__name__)
# 导入配置模块中的配置
app.config.from_object(config)
# 为当前应用程序启用WTF_CSRF保护,并返回一个CSRFProtect对象
csrf = CSRFProtect(app)
- 直接通过键值对的方式新增配置,即
app.config
[‘<配置名称>’]=值添加配置到flask
对象app
中:
from flask import Flask
from flask_wtf.csrf import CSRFProtect # 导入CSRFProtect模块
app = Flask(__name__)
app.config['SECRET_KEY'] = 'ADJLAJDLA' # 用于生成动态令牌的秘钥
app.config['CSRF_ENABLED'] = True # 用于开启CSRF保护,但默认状态下都是开启的
# 为当前应用程序启用WTF_CSRF保护,并返回一个CSRFProtect对象
csrf = CSRFProtect(app)
- 除了使用上述方法来配置
CSRF
保护,我们还需要用到flask_wtf
与wtfroms
来定义一个支持CSRF
保护的后端表单,我们一般将其定义在一个类当中;
该类需要继承基类:flask_wtf.FlaskForm
或flask_wtf.Form
,二者完全相同,但Form
即将被FlaskForm
替换,推荐使用前者!
from flask import Flask,render_template,request
from flask_wtf.csrf import CSRFProtect
# 导入表单基类FlaskForm
from flask_wtf import FlaskForm
# 导入FlaskForm父类的表单字段组件(字符串文本域,密码文本域,提交按钮)
from wtforms import StringField,PasswordField,SubmitField
# 导入FlaskForm父类的表单验证组件(数据不为空,数据是否相同,数据长度)
from wtforms.validators import DataRequired,EqualTo,Length
app = Flask(__name__)
# 配置加密匙,后端为了保护网站加入的验证机制
# 不加会报错:RuntimeError: A secret key is required to use CSRF.
app.config['SECRET_KEY'] = 'ADJLAJDLA'
# app.config['CSRF_ENABLED'] = True # 可以省略
csrf = CSRFProtect(app)
# 定义表单模型类,继承FlaskForm
class Register(FlaskForm):
# 定义表单中的元素,类似于html的form中定义input标签下的内容
# label 用于点击后跳转到某一个指定的field框
# validators 用于接收一个验证操作列表
# render_kw 用于给表单字段添加属性,各属性以键值对的形式设置
user_name = StringField(label='用户名:',validators=[DataRequired(message=u'用户名不能为空'),Length(6,16,message='长度位于6~16之间')],render_kw={
'placeholder':'输入用户名'})
# message中存放判断为错误时要返回的信息,EqualTo中第一个参数是要比较的field组件
password = PasswordField(label='密码:',validators=[DataRequired(message=u'密码不能为空'),EqualTo('password2',message=u'两次输入需相同'),Length(6,16