Flask 表单操作库 flask_WTF flask_WTForms

一、安装 flask_WTF 0.14.X 

flask_WTF 英文文档          flask_WTF 中文文档0.12        Flask表单验证组件WTForms

Flask-WTF是集成WTForms,并带有 csrf 令牌的安全表单和全局的 csrf 保护的功能。每次我们在建立表单所创建的类都是继承与flask_wtf中的FlaskForm,而FlaskForm是继承WTForms中forms。

pip install flask_WTF

二、基本用法:

1.创建基础表单

例如,form.py:

class LoginForm(FlaskForm):
    username = StringField()
    password = PasswordField()
    remember_me = BooleanField(label='Keep me logged in')

2.CSRF保护

任何使用FlaskForm创建的表单发送请求,都会有CSRF的全部保护,在对应的template中HTML渲染表单时,可以加入form.csrf_token:

app.config['SECRET_KEY'] = 'ABC'  # 指定CSRF验证字段
<form method="post">
    {{ form.csrf_token }}
</form>

但是如果模板中没有表单,则可以使用一个隐藏的input标签加入csrf_token。

<form method="post">
    <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
</form>

3.验证表单

在视图处理程序中验证请求:
view.py

def login():
    form = LoginForm()
    if form.validate_on_submit():
        return redirect('/success')
    return render_template('login.html', form=form)

使用 validate_on_submit 来检查是否是一个 POST 请求并且请求是否有效。

4.文件上传

Flask-WTF 提供 FileField 来处理文件上传,它在表单提交后,自动从 flask.request.files 中抽取数据。FileField 的 data 属性是一个 Werkzeug FileStorage 实例。

from werkzeug import secure_filename
from flask_wtf.file import FileField

class PhotoForm(Form):
    photo = FileField('Your photo')

@app.route('/upload/', methods=('GET', 'POST'))
def upload():
    form = PhotoForm()
    if form.validate_on_submit():
        filename = secure_filename(form.photo.data.filename)
        form.photo.data.save('uploads/' + filename)
    else:
        filename = None
    return render_template('upload.html', form=form, filename=filename)

注意:在 HTML 表单的 enctype 设置成 multipart/form-data,如下:

<form action="/upload/" method="POST" enctype="multipart/form-data">
    {# 把定义的表单字段写入到html中 #}
    {{ form.username }}
    {{ form.password }}
</form>

5.验证码

Flask-WTF 通过 RecaptchaField 也提供对验证码的支持:

from flask_wtf import Form, RecaptchaField
from wtforms import TextField

class SignupForm(Form):
    username = TextField('Username')
    recaptcha = RecaptchaField()

还需要配置一下信息:

字段 配置
RECAPTCHA_PUBLIC_KEY 必须 公钥
RECAPTCHA_PRIVATE_KEY 必须 私钥
RECAPTCHA_API_SERVER 可选 验证码 API 服务器
RECAPTCHA_PARAMETERS 可选 一个 JavaScript(api.js)参数的字典
RECAPTCHA_DATA_ATTRS 可选 一个数据属性项列表 https://developers.google.com/recaptcha/docs/display

三、WTForms

3.1、基本了解

WTForms是一个Flask集成的框架,或者是说库。用于处理浏览器表单提交的数据。它在Flask-WTF 的基础上扩展并添加了一些随手即得的精巧的帮助函数,这些函数将会使在 Flask 里使用表单更加有趣。

3.2、用法:

1.field字段

WTForms支持HTML字段:

字段类型 说明
StringField 文本字段, 相当于type类型为text的input标签
TextAreaField 多行文本字段
PasswordField 密码文本字段
HiddenField 隐藏文本字段
DateField 文本字段, 值为datetime.date格式
DateTimeField 文本字段, 值为datetime.datetime格式
IntegerField 文本字段, 值为整数
DecimalField 文本字段, 值为decimal.Decimal
FloatField 文本字段, 值为浮点数
BooleanField 复选框, 值为True 和 False
RadioField 一组单选框
SelectField 下拉列表
SelectMultipleField 下拉列表, 可选择多个值
FileField 文件上传字段
SubmitField 表单提交按钮
FormFiled 把表单作为字段嵌入另一个表单
FieldList 子组指定类型的字段

2.Validators验证器

WTForms可以支持很多表单的验证函数:

验证函数 说明
Email 验证是电子邮件地址
EqualTo 比较两个字段的值; 常用于要求输入两次密钥进行确认的情况
IPAddress 验证IPv4网络地址
Length 验证输入字符串的长度
NumberRange 验证输入的值在数字范围内
Optional 无输入值时跳过其它验证函数
DataRequired 确保字段中有数据
Regexp 使用正则表达式验证输入值
URL 验证url
AnyOf 确保输入值在可选值列表中
NoneOf 确保输入值不在可选列表中

3.自定义Validators验证器

第一种:in_line Validator(内联验证器)
也就是自定义一个验证函数,在定义表单类的时候,在对应的字段中加入该函数进行认证。下面的my_length_check函数就是用于判name字段长度不能超过50.

def my_length_check(form, field):
    if len(field.data) > 50:
        raise ValidationError('Field must be less than 50 characters')

class MyForm(Form):
    name = StringField('Name', [InputRequired(), my_length_check])

第二种:通用且可重用的验证函数
一般是以validate开头,加上下划线再加上对应的field字段(validate_filed),浏览器在提交表单数据时,会自动识别对应字段所有的验证器,然后执行验证器进行判断。

class RegistrationForm(FlaskForm):
    email = StringField(
        'Email', 
        validators=[
            DataRequired(), 
            Length(1, 60), 
            Email()
        ]
    )
    username = StringField(
        'Username', 
        validators=[
            DataRequired(), 
            Length(1, 60),
            Regexp(
                '^[A-Za-z][A-Za-z0-9_.]*$', 
                0, 
                'username must have only letters, numbers dots or underscores'
            )
        ]
    )
    password = PasswordField(
        'Password', 
        validators=[
            DataRequired(), 
            EqualTo(
                'password2', 
                message='password must match'
            )
        ]
    )
    password2 = PasswordField(
        'Confirm password', 
        validators=[
            DataRequired()
        ]
    )

    def validate_email(self, field):
        if User.objects.filter(email=field.data).count() > 0:
            raise ValidationError('Email already registered')

    def validate_username(self, field):
        if User.objects.filter(username=field.data).count() > 0:
            raise ValidationError('Username has exist')

第三种:比较高级的validators

class Length(object):
    def __init__(self, min=-1, max=-1, message=None):
        self.min = min
        self.max = max
        if not message:
            message = u'Field must be between %i and %i characters long.' % (min, max)
        self.message = message

    def __call__(self, form, field):
        l = field.data and len(field.data) or 0
        if l < self.min or self.max != -1 and l > self.max:
            raise ValidationError(self.message)

length = Length

4.Widget组件

下面可以以登录界面为实例:
login.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from flask import Flask, render_template, request, redirect
from wtforms import Form
from wtforms import validators
from wtforms import widgets

class LoginForm(Form):
    name = simple.StringField(
        label='用户名',
        validators=[
            validators.DataRequired(message='用户名不能为空.'),
        ],
        widget=widgets.TextInput(),
        render_kw={'class': 'form-control'}
    )
    pwd = simple.PasswordField(
        label='密码',
        validators=[
            validators.DataRequired(message='密码不能为空.'),
        ],
        widget=widgets.PasswordInput(),
        render_kw={'class': 'form-control'}
    )

四、常用方法

# form对象,Movie创建的表单类
form = Movie()

# 获取form表单提交过来的数据(元组)
data = form.data

# 设置单个form字段信息:form.字段名.data = '内容'
form.star.data = 'Hello word!'

# 获取上传文件信息:form.字段名.data.filename
logo = form.url.data.filename

# 保存表单上传内容到文件夹:form.字段名.data.save(保存路径,保存文件)
form.logo.data.save(app.config['UP_DIR'],url)

猜你喜欢

转载自blog.csdn.net/u011146423/article/details/87872663
今日推荐