Flask-WTF 和图形验证码

Flask-WTF

表单处理的扩展库,提供了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/路由,获取图形码。

你可能感兴趣的:(Python)