Flask中WTForm用法详解

1、WTForms介绍和基本使用

1.1 WTForm介绍

这个插件库主要有两个作用。

第一个是做表单验证,将用户提交上来的数据进行验证是否符合系统要求。

第二个是做模版渲染。 (了解即可)

官网:https://wtforms.readthedocs.io/en/latest/index.html

        Flask-WTF是简化了WTForms操作的一个第三方库。WTForms表单的两个主要功能是验证用户提交数据的合法性以及渲染模板。而Flask-WTF还包括一些其他的功能:CSRF保护,文件上传等。

安装Flask-WTF默认也会安装WTForms,因此使用以下命令来安装Flask-WTF和WTForms:

pip install flask-wtf

1.2 WTForms表单验证的基本使用

  1. 自定义一个表单类,继承自wtforms.Form类。
  2. 定义好需要验证的字段,字段的名字必须和模版中那些需要验证的input标签的name属性值保持一致。
  3. 在需要验证的字段上,需要指定好具体的数据类型。
  4. 在相关的字段上,指定验证器。
  5. 以后在视图函数中,只需要使用这个表单类的对象,并且把需要验证的数据,也就是request.form传给这个表单类,再调用表单类对象.validate()方法进行,如果返回True,那么代表用户输入的数据都是符合格式要求的,Flase则代表用户输入的数据是有问题的。如果验证失败了,那么可以通过表单类对象.errors来获取具体的错误信息。

示例代码:

main.py

from flask import Flask, render_template, request
from wtforms import Form, StringField
from wtforms.validators import Length, EqualTo


app = Flask(__name__)


@app.route('/')
def index():
    return 'hello world'


class RegisterForm(Form):
    uname = StringField(validators=[Length(min=2, max=10, message='用户名长度2-10之间')])
    pwd = StringField(validators=[Length(min=2, max=10)])
    pwd2 = StringField(validators=[Length(min=2, max=10), EqualTo('pwd', message='2次密码不一致')])


@app.route('/register/', methods=['GET', 'POST'])
def register():
    if request.method == 'GET':
        return render_template('register.html')
    else:
        form = RegisterForm(request.form)
        if form.validate():  # 验证成功:True, 失败:False
            return '验证成功'
        else:
            return f'验证失败!{form.errors}'


if __name__ == '__main__':
    app.run(debug=True)

register.html




    
    
    
    注册


    
用户名:
密码:
确认密码:

运行结果:

Flask中WTForm用法详解_第1张图片

Flask中WTForm用法详解_第2张图片

Flask中WTForm用法详解_第3张图片

Flask中WTForm用法详解_第4张图片

Flask中WTForm用法详解_第5张图片

Flask中WTForm用法详解_第6张图片

Flask中WTForm用法详解_第7张图片

2、WTForm常用验证器

        页面把数据提交上来,需要经过表单验证,进而需要借助验证器来进行验证,以下是常用的内置验证器。

2.1 Length

        字符串长度限制,有min和max两个值进行限制,message用于提示信息。

username = StringField(validators=[Length(min=3,max=10,message="用户名长度必须在3到10位之间")])

2.2 EqualTo

        验证数据是否和另外一个字段相等,常用的就是密码和确认密码两个字段是否相等。

password_repeat = StringField(validators=[Length(min=6,max=10),EqualTo("password")])

2.3 Email

        验证上传的数据是否为邮箱数据格式 如:[email protected]

email = StringField(validators=[Email()])

2.4 InputRequired

        验证该项数据为必填项,即要求该项非空。

username = StringField(validators=[input_required()])

2.5 NumberRange

        数值的区间,有min和max两个值限制,如果处在这两个数字之间则满足。

age = IntegerField(validators=[NumberRange(12,18)])

2.6 Regexp

        定义正则表达式进行验证,如验证手机号码。

phone = StringField(validators=[Regexp(r'1[34578]\d{9}')])

2.7 URL

        必须是URL的形式 如http://www.baicu.com。

home_page = StringField(validators=[URL()])

2.8 UUID

        验证数据是UUID类型。

uuid = StringField(validators=[UUID()])

2.9 实例演示

示例代码:

main.py

from flask import Flask, render_template, request
from formcheck import RegisterForm


app = Flask(__name__)


@app.route('/')
def index():
    return 'Hello! '


@app.route('/register/', methods=['GET', 'POST'])
def register():
    if request.method == 'GET':
        return render_template('register.html')
    else:
        form = RegisterForm(request.form)
        if form.validate():
            return '验证成功!'
        else:
            return f'验证失败!{form.errors}'


if __name__ == '__main__':
    app.run(debug=True)

formcheck.py

from wtforms import Form, StringField, IntegerField
from wtforms.validators import Email, InputRequired, NumberRange, Regexp, URL, UUID


class RegisterForm(Form):
    # pip install wtforms[email]
    email = StringField(validators=[Email()])
    uname = StringField(validators=[InputRequired()])
    age = IntegerField(validators=[NumberRange(min=18, max=50)])
    phone = StringField(validators=[Regexp('^1[3456789]\d{9}$')])
    homepage = StringField(validators=[URL()])
    uuid = StringField(validators=[UUID()])

register.html




    
    注册页面


  
邮箱:
用户名:
年龄:
手机号码:
个人主页:
uuid:

运行结果:

Flask中WTForm用法详解_第8张图片

Flask中WTForm用法详解_第9张图片

Flask中WTForm用法详解_第10张图片

3、WTForms自定义验证器

只有当WTForms内置的验证器不够使的时候,才需要使用自定义验证器。

如果想要对表单中的某个字段进行更细化的验证,那么可以针对这个字段进行单独的验证。

自定义验证器步骤如下:

  1. 定义一个方法,方法的名字规则是: validate_字段名(self,field) 。
  2. 在方法中,使用 field.data 可以获取到这个字段的具体的值。
  3. 验证时,如果数据满足条件,那么可以什么都不做。如果验证失败,那么应该抛出一个 wtforms.validators.ValidationError 的异常,并且把验证失败的信息传到这个异常类中。

示例代码:

main.py

from flask import Flask, render_template, request, session
from formcheck import LoginForm
from random import randint
import os


app = Flask(__name__)
app.config['SECRET_KEY'] = os.urandom(32)


@app.route('/')
def index():
    return 'Hello! '


@app.route('/login/', methods=['GET', 'POST'])
def register():
    if request.method == 'GET':
        code = randint(1000, 9999)
        session['code'] = code
        return render_template('login.html', code=code)
    else:
        form = LoginForm(request.form)
        if form.validate():
            return '验证成功!'
        else:
            return f'验证失败!{form.errors}'


if __name__ == '__main__':
    app.run(debug=True)

formcheck.py

from wtforms import Form, StringField
from wtforms.validators import Length, ValidationError
from flask import session


class LoginForm(Form):
    code = StringField(validators=[Length(4, 4)])  # 不能满足数据内容的匹配

    def validate_code(self, field):
        font_code = field.data
        server_code = str(session.get('code'))

        print(f'前端的数据是:{font_code} ==== 服务器端的数据是:{server_code}')
        print(f'前端的数据是:{type(font_code)} ==== 服务器端的数据是:{type(server_code)}')
        if font_code != server_code:
            raise ValidationError('验证码错误')

login.html




    
    注册页面


  
用户名:
密码:
验证码: {{code}}

运行结果:

Flask中WTForm用法详解_第11张图片

Flask中WTForm用法详解_第12张图片

Flask中WTForm用法详解_第13张图片

Flask中WTForm用法详解_第14张图片

Flask中WTForm用法详解_第15张图片

Flask中WTForm用法详解_第16张图片

4、WTForms渲染模板

渲染模版是WTForms的第二个作用。

示例代码:

main.py

from flask import Flask, render_template, request
from formcheck import LoginForm


app = Flask(__name__)


@app.route('/')
def index():
    return 'Hello! '


@app.route('/login/', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        form = LoginForm()
        return render_template('login.html', form=form)
    else:
        return '登录成功'


if __name__ == '__main__':
    app.run(debug=True)

formcheck.py

from wtforms import Form, StringField, IntegerField, BooleanField, SelectField
from wtforms.validators import Length, InputRequired, NumberRange


class LoginForm(Form):
    uname = StringField(validators=[Length(min=2, max=10)])
    # uname = StringField('用户名:',validators=[Length(min=1,max=10)])
    age = IntegerField('年龄:', validators=[InputRequired(), NumberRange(min=15, max=25)])
    remember = BooleanField('记住我:')
    address = SelectField('地址:', choices=[('bj', '北京'), ('sh', '上海'), ('gz', '广州')])

login.html




    
    
    
    Document
    


    
{{ form.uname.label}} {{ form.uname(class='hot')}}
{{ form.age.label}} {{ form.age() }}
{{ form.remember.label}} {{ form.remember()}}
{{ form.address.label}} {{ form.address()}}

运行结果:

Flask中WTForm用法详解_第17张图片

Flask中WTForm用法详解_第18张图片

问题遗留

上面代码执行中,WTforms渲染模板验证没有生效!

5、Flask-wtf验证上传的文件

关键点:

  1. 定义验证表单类的时候,对文件类型的字段,需要采用 FileField 这个类型,即wtforms.FileField
  2. 验证器需要从 flask_wtf.file 中导入。 flask_wtf.file.FileRequired 和 flask_wtf.file.FileAllowed
  3. flask_wtf.file.FileRequired 是用来验证文件上传不能为空。
  4. flask_wtf.file.FileAllowed 用来验证上传的文件的后缀名, 如常见图片后缀 .jpg 和.png以及.gif等。
  5. 在视图函数中,需要使用 from werkzeug.datastructures import CombinedMultiDict 来把request.form 与 request.files 来进行合并。
  6. 最后使用 表单验证对象.validate()进行验证。

示例代码:

main.py

from flask import Flask, render_template, request
from werkzeug.datastructures import CombinedMultiDict
from werkzeug.utils import secure_filename
import os
from formcheck import UpLoadForm

app = Flask(__name__)
UPLOAD_PATH = os.path.join(os.path.dirname(__file__), 'images')


@app.route('/upload/', methods=['GET', 'POST'])
def upload():
    if request.method == 'GET':
        return render_template('upload.html')
    else:
        form = UpLoadForm(CombinedMultiDict([request.form, request.files]))
        if form.validate():
            img_file = form.pic.data
            file_name = secure_filename(img_file.filename)
            img_file.save(os.path.join(UPLOAD_PATH, file_name))
            return '上传文件成功!'
        else:
            return f'{form.errors}'


if __name__ == '__main__':
    app.run(debug=True)

formcheck.py

from wtforms import Form, FileField
from flask_wtf.file import FileAllowed, FileRequired


class UpLoadForm(Form):
    pic = FileField(validators=[FileRequired(), FileAllowed(['jpg', 'png', 'gif'])])

upload.py




    
    
    
    Document


    
上传文件:

运行结果:

Flask中WTForm用法详解_第19张图片

Flask中WTForm用法详解_第20张图片

Flask中WTForm用法详解_第21张图片

Flask中WTForm用法详解_第22张图片

Flask中WTForm用法详解_第23张图片

Flask中WTForm用法详解_第24张图片

你可能感兴趣的:(Flask框架,flask,python,WTForms)