本章主题
关键词
Flask-WTF
Flask-WTF 是简化了 WTForms 操作的⼀个 第三⽅库。WTForms 表单的 两个主要功能 是 验证⽤户提交数据的合法性 以及 渲染模板。当然还包括⼀些 其他的功能:CSRF保护,文件上传 等。安装 Flask-WTF 也会默认安装 WTForms,因此使⽤以下命令来安装 Flask-WTF :
pip install flask-wtf
表单验证
安装完 flask-wtf
后。来看下第⼀个功能,就是用 表单 来做 数据验证,现在有⼀个 forms.py
⽂件,然后在⾥⾯创建⼀个 RegistForm
的注册验证表单 :
class RegistForm(Form):
name = StringField(validators=[length(min=4,max=25)])
email = StringField(validators=[email()])
password = StringField(validators=[DataRequired(),length(min= 6,max=10),EqualTo('confirm')])
confirm = StringField()
在这个里面指定了需要上传的参数,并且 指定 了 验证器,⽐如 name
的⻓度应该在4-25之间。email
必须要满⾜邮箱的格式。password
⻓度必须在6-10之间, 并且应该和 confirm
相等才能通过验证。
写完表单后,接下来就是 regist.html
⽂件 :
<form action="/regist/" method="POST">
<table>
<tr>
<td>⽤户名:</td>
<td><input type="text" name="name"></td>
</tr>
<tr>
<td>邮箱:</td>
<td><input type="email" name="email"></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td>确认密码:</td>
<td><input type="password" name="confirm"></td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="提交"></td>
</tr>
</table>
</form>
再来看视图函数 regist
:
@app.route('/regist/',methods=['POST','GET'])
def regist():
form = RegistForm(request.form)
if request.method == 'POST' and form.validate():
user = User(name=form.name.data,email=form.email.data,pass word=form.password.data)
db.session.add(user)
db.session.commit()
return '注册成功!'
return render_template('regist.html')
RegistForm
传递的是 request.form
进去进⾏初始化,并且判断 form.validate
会返回⽤户提交的数据是否满足表单的验证。
渲染模板
form
还可以 渲染模板,让你少写了⼀丢丢的代码,⽐如重写以上例⼦, RegistForm
表单代码如下:
class RegistForm(Form):
name = StringField('⽤户名:',validators=[length(min=4,max=25)])
email = StringField('邮箱:'validators=[email()])
password = StringField('密码:', validators=[DataRequired(), length(min=6, max=10),EqualTo('confirm')])
confirm = StringField('确认密码:')
以上增加了第⼀个位置参数,⽤来在 html
⽂件中,做标签提示作⽤。
在 app
中的视图函数中,修改为如下:
@app.route('/regist/',methods=['POST','GET'])
def regist():
form = RegistForm(request.form)
if request.method == 'POST' and form.validate():
user = User(name=form.name.data,email=form.email.data,pass word=form.password.data)
db.session.add(user)
db.session.commit()
return '注册成功!'
return render_template('regist.html',form=form)
以上唯⼀的不同是在渲染模板的时候传⼊了 form
表单参数进去,这样在模板中就可以使⽤表单 form
变量了。
接下来看下 regist.html
文件:
<form action="/regist/" method="POST">
<table>
<tr>
<td>{{ form.name.label }}</td>
<td>{{ form.name() }}</td>
</tr>
<tr>
<td>{{ form.email.label }}</td>
<td>{{ form.email() }}</td>
</tr>
<tr>
<td>{{ form.password.label }}</td>
<td>{{ form.password() }}</td>
</tr>
<tr>
<td>{{ form.confirm.label }}</td>
<td>{{ form.confirm() }}</td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="提交"></td>
</tr>
</table>
</form>
文件上传
- 在模版中,
form
表单中,需要指定encotype='multipart/form- data'
才能上传⽂件; - 在后台如果想要获取上传的⽂件,那么应该使⽤
request.files.get('avatar')
来获取; - 保存⽂件之前,先要使⽤
werkzeug.utils.secure_filename
来对上传 上来的⽂件名进⾏⼀个过滤。这样才能保证不会有安全问题; - 获取到上传上来的⽂件后,使⽤
avatar.save(路径)
⽅法来保存⽂件; - 从服务器上读取⽂件,应该定义⼀个
url
与视图函数,来获取指定的⽂件。在 这个视图函数中,使⽤send_from_directory(⽂件的⽬录,⽂件名)
来获取。
@app.route('/upload/',methods=['GET','POST'])
def upload():
if request.method == 'GET':
return render_template('upload.html')
else:
# 获取描述信息
desc = request.form.get("desc")
avatar = request.files.get("avatar")
filename = secure_filename(avatar.filename)
avatar.save(os.path.join(UPLOAD_PATH,filename))
print(desc)
return '⽂件上传成功'
@app.route('/images/<filename>/')
def get_image(filename):
return send_from_directory(UPLOAD_PATH,filename)
对上传⽂件使⽤表单验证:
- 定义表单的时候,对⽂件的字段,需要采⽤
FileField
这个类型; - 验证器应该从
flask_wtf.file
中导⼊;flask_wtf.file.FileRequired
是⽤来验证⽂件上传是否为空;flask_wtf.file.FileAllowed
⽤来验证上传的⽂件的后缀名; - 在视图⽂件中,使⽤
from werkzeug.datastructures import CombinedMultiDict
来把request.form 与 request.files
来进⾏合并;再传给表单来验证。
from werkzeug.datastructures import CombinedMultiDict、
form = UploadForm(CombinedMultiDict([request.form,request.files]))
解决中⽂问题: https://blog.youkuaiyun.com/qq_36390239/article/details/98847888
总结小便条
本篇文章主要讲了以下几点内容:
本章回顾暂时就到这了,如果还有点晕,那就把文章里所有引用的案例代码再敲几遍吧。拜拜~