flask-wtf 是简化了Flask-WTForms的第三方库,wtfroms表单验证的两个主要功能是,验证用户数据提交的合法性和渲染模板,也包括一些其他的功能,如CSRF保护,文件上传等。安装flask-wtf默认也会安装WTForms.
pip install flask-wtf
from wtforms import Form, StringField,IntegerField
from wtforms.validators import length, EqualTo, Email,NumberRange,InputRequired
from wtforms.validators import Regexp,URL,Length,ValidationError
#各类表单验证
class RegistForm(Form):
username = StringField(validators=[length(min=3, max=10, message='用户名长度不正确')])
password = StringField(validators=[length(min=3, max=10, message='密码长度不正确')])
password_verify = StringField(validators=[EqualTo('password', message='两次密码长度不相等')])
上面的例子,指定了username 的长度,password密码长度,输入的密码需要和password_verify相等才能通过验证。
#email表单验证
class LoginForm(Form):
# email = StringField(validators=[Email(message='格式不正确')])
#NumberRange表单
# age = IntegerField(validators=[NumberRange(1, 80)])
#InputRequired表单
# username = StringField(validators=[InputRequired()])
#做个手机验证
# telphone = StringField(validators=[Regexp(r'1[3589]\d{9}')])
# 正则表达式,第一个为1,第二个为(3589)任意,后面九个任意。
#URL表单
# info = StringField(validators=[URL()])
#验证码表单
captche = StringField(validators=[Length(min=4,max=4)])
#想验证验证码必须使用下面的方法validate_captche,加下划线+需要验证的数据,进行验证,否则失败
def validate_captche(self, field):
if field.data != '5678':
raise ValidationError('验证码错误') #ValidationError 可允许传出的错误
完成表单后就需要导入html文件了
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="" method="post">
<!-- <table>-->
<!-- <tr>-->
<!-- <td>邮箱:</td>-->
<!-- <td><input type="text" name="email"></td>-->
<!-- </tr>-->
<!-- <tr>-->
<!-- <td><input type="submit" value="提交"></td>-->
<!-- </tr>-->
<!-- </table>-->
<!-- <table>-->
<!-- <tr>-->
<!-- <td>年龄:</td>-->
<!-- <td><input type="text" name="age"></td>-->
<!-- </tr>-->
<!-- <tr>-->
<!-- <td><input type="submit" value="提交"></td>-->
<!-- </tr>-->
<!-- </table>-->
<!-- <table>-->
<!-- <tr>-->
<!-- <td>用户名:</td>-->
<!-- <td><input type="text" name="username"></td>-->
<!-- </tr>-->
<!-- <tr>-->
<!-- <td><input type="submit" value="提交"></td>-->
<!-- </tr>-->
<!-- </table>-->
<!-- <table>-->
<!-- <tr>-->
<!-- <td>手机号:</td>-->
<!-- <td><input type="text" name="telphone"></td>-->
<!-- </tr>-->
<!-- <tr>-->
<!-- <td><input type="submit" value="提交"></td>-->
<!-- </tr>-->
<!-- </table>-->
<!--<table>-->
<!-- <tr>-->
<!-- <td>个人中心:</td>-->
<!-- <td><input type="text" name="info"></td>-->
<!-- </tr>-->
<!-- <tr>-->
<!-- <td><input type="submit" value="提交"></td>-->
<!-- </tr>-->
<!--</table>-->
<table>
<tr>
<td>验证码:</td>
<td><input type="text" name="captche"></td>
</tr>
<tr>
<td><input type="submit" value="提交"></td>
</tr>
</table>
</body>
</html>
from flask import Flask,request,render_template
from forms import RegistFrom,LoginForm
app = Flask(__name__)
# @app.route('/',methods=("GET","POST"))
# def login():
# if request.method == "GET":
# return render_template('index.html')
# else:
# form = RegistFrom(request.form)
# if form.validate():
# return '登录成功'
# else:
# print(form.errors)
# return '登录失败'
@app.route('/login/',methods=["GET","POST"])
def login():
if request.method == "GET":
return render_template('index.html')
else:
form = LoginForm(request.form)
if form.validate():
return '登录成功'
else:
print(form.errors)
return '登录失败'
if __name__ == '__main__':
app.run(debug=True,port=8384)
form 还可以渲染模板,少写一点点代码,如下重写例子:
####例子:
class RegistForm(Form):
username = StringField(validators=[length(min=3, max=10, message='用户名长度不正确')])
password = StringField(validators=[length(min=3, max=10, message='密码长度不正确')])
password_verify = StringField(validators=[EqualTo('password', message='两次密码长度不相等')])
========================================================================
### 重写例子:
@app.route('/login/',methods=["GET","POST"])
def login():
form = RegistForm(request.form)
if request == "POST" and form.validate():
user = User(username = form.username.date,password = form.password.date)
db.session.add(user)
db.session.commit()
return "注册成功"
return render_template('index.html',form = form)
以上不同的地方在于渲染模板的时候添加了参数form,这样在模板中就可以使用表单form变量
如下:
==============主文件===============
from flask import Flask, request, render_template
import os
from werkzeug.utils import secure_filename
from werkzeug.datastructures import CombinedMultiDict
from forms import UploadForm
app = Flask(__name__)
# @app.route('/')
# def index():
# return 'aaa'
@app.route('/upload/',methods=('GET','POST'))
def upload1():
if request.method == 'GET':
return render_template('upload.html')
else:
# desc = request.form.get('desc')
# image_file = request.files.get('image_file')
# #判断名称,不支持中文格式,如上传文件包含中文,会自动去除
# filename = secure_filename(image_file.filename)
# image_file.save(os.path.join('images', filename))
# return "文件保存成功"
form = UploadForm(CombinedMultiDict([request.form, request.files])) #进行合并,在传给表单验证
print(form)
if form.validate():
desc = request.form.get('desc')
image_file = request.files.get('image_file')
filename = secure_filename(image_file.filename)
image_file.save(os.path.join('images', filename))
return "文件保存成功"
else:
print(form.errors)
return '文件上传失败'
=====从服务器上读取文件,建立一个视图函数
@app.route('/images/<filename>/')
def get_image(filename)
return send_form_directory(路径,文件名)
模板文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--#文件上传表单必须添加enctype="multipart/form-data" 这个属性-->
<form action="" method="post" enctype="multipart/form-data">
<table>
<tr>
<td>头像</td>
<td><input type="file" name="image_file"></td>
</tr>
<tr>
<td>描述</td>
<td><input type="text" name="desc"></td>
</tr>
<tr>
<td><input type="submit" value='上传'></td>
</tr>
</table>
</form>
</body>
</html>
#设置表单验证
from wtforms import Form, FileField, StringField
from wtforms.validators import Regexp, InputRequired
from flask_wtf.file import FileAllowed, FileRequired
class UploadForm():
# 对上传的文件进行验证
image_file = FileField(validators=[FileRequired(), FileAllowed(['jpg', 'png'])])
desc = StringField(validators=[InputRequired()])