表单处理的扩展库,提供了CSRF、字段校验等功能,使⽤⾮常⽅便
安装: pip install flask-wtf
注册表单类
from flask_wtf import FlaskForm # 导⼊表单基类
from wtforms import StringField,PasswordField,SubmitField
from wtforms.validators import DataRequired,Length,EqualTo,Email
# 自定义表单注册类
class Register(FlaskForm):
username = StringField() # 用户名
password = PasswordField() # 密码
pwdagain = PasswordField() # 重复密码
email = EmailField(validators=[Email("邮箱格式错误")])
# wtforms.validators中的Regexp类可以使用正则表达式
phonenum = StringField(validators=[Regexp(r'^(13\d|14[5|7]|15\d|166|17[3|6|7]|18\d)\d{8}$')])
添加视图函数,创建表单对象,并渲染模板⽂件
from form import Register # 导入自定义的表单注册类
@app.route('/register/', methods=['GET', 'POST'])
def register():
form = Register() # 实例化表单类
if request.method == 'POST':
# 这个⽅法是实现表单校验功能的 csrf,数据正确性 都通过了 则为真 否则为假
if form.validate_on_submit():
# print(request.form)
print(form.username) #拿到username的整个标签
print(form.username.data) #取出username⾥⾯的value值
return '数据提交成功'
return render_template(('register.html', **locals())
原生渲染表单
<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2>flask-wtf的表单类</h2>
<form action="{{ url_for('register') }}" method="post">
{# csrf #}
{{ form.csrf_token }}
{{ form.username.label }}
{{form.username(style="color:red;",class='myself',placeholder='请输⼊⽤户名...') }}
#给当前的标签添加属性和值 关键字参数
#循环迭代取出验证失败的错误信息(也就是你在验证器⾥的属性message的值)
{% for error in form.username.errors %}
<span style="color:red;">{{ error }}</span>
{% endfor %}
<br>
{{ form.userpass.label }}
{{ form.userpass }}
{% for error in form.password.errors %}
<span style="color:red;">{{ error }}</span>
{% endfor %}
<br>
{{ form.confirm.label }}
{{ form.confirm() }}
{% for error in form.pwdagain.errors %}
<span style="color:red;">{{ error }}</span>
{% endfor %}
<br>
{{ form.email.label }}
{{ form.email() }}
{% for error in form.email.errors %}
<span style="color:red;">{{ error }}</span>
{% endfor %}
<br>
{{ form.submit() }}
</form>
</body>
</html>
字段类型 | 说明 |
---|---|
StringField | 普通⽂本字段 |
Submit | Submit 提交按钮 |
PasswordField | 密⽂字段 |
HiddenField | 隐藏字段 |
RadioField | 单选框 |
BooleanField | 复选框 |
FileField | ⽂件上传 |
SelectField | 下拉框 |
TextAreaField | ⽂本域 |
IntegerField | ⽂本字段,值为整数 |
FloatField | ⽂本字段,值为浮点数 |
DateField | datetime.date类型 |
DateTimeField | datetime.datetime类型 |
PIL:Python Imaging Library,已经是Python平台事实上的图像处理标准库了。PIL功能⾮常强⼤,但API却⾮常简单易⽤。
由于PIL仅⽀持到Python 2.7,因为长时间没有维护,于是⼀群志愿者在PIL的基础上创建了兼容的版本,名字叫Pillow,⽀持最新Python 3.x,⼜加⼊了许多新特性。
安装Pillow库
安装: pip install pillow
# Vcode.py
import os
from io import BytesIO
from random import randint
from PIL import Image, ImageFont, ImageDraw
class vcode:
def __init__(self,width=100, height=34, size=4):
self.width = width
self.height = height
self.size = size
self.__code = '' # 验证码字符串
self.pen = None # 画笔
@property # 装饰器访问私有化属性
def code(self):
return self.__code
def generate(self):
# 1.创建画布,颜色随机
im = Image.new("RGB", (self.width, self.height),self.__rand_color(150))
self.pen = ImageDraw.Draw(im) # 在画布上创建画笔
# 2.生成验证码字符串
self.__rand_string()
# 3.画验证码
self.__draw_code()
# 4.画干扰点
self.__draw_point()
# 5.画干扰线
self.__rand_line()
# 6.返回验证码图片
buf = BytesIO() # 缓冲区
im.save(buf, 'png') # 以pug格式将图片保存在缓冲区
res = buf.getvalue() # 获取图片的二进制
return res
# 创建个随机颜色的函数,数字越接近0颜色越浓,越接近255颜色越淡
def __rand_color(self, min=0, max=255):
return randint(min, max), randint(min, max), randint(min, max)
# 生成验证码字符串
def __rand_string(self):
self.__code = "" # 每次生成字符串前将之前缓存字符串重置为空
for i in range(self.size):
self.__code += str(randint(0, 9))
# 画验证码
def __draw_code(self):
# 加载字体
path = os.path.join(os.getcwd(),'static/fonts/SIMLI.TTF')
# 设置字体大小和编码格式
font1 = ImageFont.truetype(path, size=20, encoding="utf-8")
# 计算字符串宽度
width = (self.width - 20) // self.size
# 逐个画字
for i in range(len(self.__code)):
x = 13 + width * i # 计算字符的x坐标
# 写入字,并随机颜色
self.pen.text((x, 7), self.__code[i], font=font1, fill=self.__rand_color(0, 80))
# 画点
def __draw_point(self):
for i in range(100):
self.pen.point((randint(1, self.width-1), randint(1, self.height-1)), self.__rand_color(30, 100))
# 画线
def __rand_line(self):
for i in range(5):
# 逐个画线,随机起始点和结束点,并随机颜色
self.pen.line([(randint(1, self.width-1), randint(1, self.height-1)),
(randint(1, self.width-1), randint(1, self.height-1))], fill=self.__rand_color(50,150), width=2)
vc = vcode() # 单例属性
# views.py
from Vcode import vc
# 验证码
@app.route("/verify/")
def verify_code():
result = vc.generate()
# 把验证码字符串保存到session
session['code'] = vc.code
# 创建响应对象
response = make_response(result)
response.headers["Content-Type"] = "image/png"
return response
这样就可以通过/verify/路由,获取图形码。