Flask-WTF与WTForms的用法详解

前言

咱们在使用flask框架来搭建本身的博客,只要是设涉及到表单相关,必然会想起Flask-WTF与WTForms。对于flask初学者来讲,比较容易混淆二者。今天想来一一解释二者的用法。html

Flask-WTF

基本了解

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

用法:

1.建立基础表单

例如,form.py:git

class LoginForm(FlaskForm): username = StringField() password = PasswordField() remember_me = BooleanField(label='Keep me logged in') 
2.CSRF保护

任何使用FlaskForm建立的表单发送请求,都会有CSRF的所有保护,在对应的template中HTML渲染表单时,能够加入form.csrf_token:github

<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.pyflask

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

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

4.文件上传

Flask-WTF 提供 FileField 来处理文件上传,它在表单提交后,自动从 flask.request.files 中抽取数据。FileFielddata 属性是一个 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"> .... </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

基本了解

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

用法:

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'} ) 

总结

其实flask表单这一部分咱们都是使用Flask-WTF与WTForms来进行实现,好比说作一下简单的系统登陆界面、注册界面等等,能够利用它们来作一些小demo,你就能够深刻理解它的原理而且能够强化flask的基础。若是不懂的,也但愿你们能够参考我最近作的开源项目SimpleBlog,里面大量应用到Flask-WTF与WTForms。

参考连接:
1.https://wtforms.readthedocs.io/en/stable/
2.https://flask-wtf.readthedocs.io/en/stable/

做者:BourneKing 连接:https://www.jianshu.com/p/7e16877757f8 来源:简书 著做权归做者全部。商业转载请联系做者得到受权,非商业转载请注明出处。
相关文章
相关标签/搜索