Flask-8 flask-wtf的使用(灵活的表单验证)

文章目录

        • 介绍:
      • 一、具体实现案例:
        • 1、创建表单类
        • 2、视图中使用
        • 3、模版中的使用
        • 4、运行后访问查看提示
      • 二、总结:

介绍:

Flask-WTF 提供了简单地 WTForms 的集成。

WTForms是一个灵活的表单验证和渲染库,用于Python
Web开发。它可以与您选择的任何Web框架和模板引擎一起使用。它支持数据验证、CSRF 保护、国际化 (I18N)
等。有各种社区库提供了与流行框架的更紧密集成。

为什么要用WTF,WT Forms是用于提供用户界面的灵活的表单呈现和验证库

WTForms文档:https://wtforms.readthedocs.io/en/3.0.x/
Flask-WTF文档:http://www.pythondoc.com/flask-wtf/


用 pip 安装 Flask-WTF 是十分简单的:

pip install Flask-WTF
# 下载的内容会包含wtforms包

该模块包含一个Form类, 该类被视为所有与表单相关的操作的父类。

一、具体实现案例:

1、创建表单类

内容:主要为页面输入中各种规则的显示

"""
@File: formtest.py
"""
import re
from flask_wtf import FlaskForm
from flask_wtf.file import FileRequired, FileField, FileAllowed
from wtforms import StringField, PasswordField
from wtforms.validators import DataRequired, Length, ValidationError, EqualTo
"""
从 0.9.0 版本开始,Flask-WTF 将不会从 wtforms 中导入任何的内容.
用户必须自己从 wtforms 中导入字段。
"""class UserForm(FlaskForm):name = StringField(label='用户名',validators=[DataRequired(),  # validators:验证器Length(min=6,max=12,message='用户名长度必须在6到12位之间')])phone = StringField(label='手机号码',validators=[DataRequired(),Length(min=11, max=11, message='手机号码必须是11位数字')])password = PasswordField(label='密码',validators=[DataRequired(),Length(min=6, max=12,message='密码长度必须在6到12位之间')])repassword = PasswordField(label='确认密码',validators=[DataRequired(),Length(min=6, max=12, message='密码长度必须在6到12位之间'),EqualTo('password', '两次密码不一致')])user_img = FileField(label='用户头像',validators=[FileRequired(),FileAllowed(['jpg', 'png', 'jpeg'],message='用户头像必须是图片格式')])def validate_name(self, data):  # 自定义表单验证# 重写了方法 validate_on_submit--继承->> self.validate()--继承->> validate()# 可查看下面的截图print('---->>>', self.name.data, '==', data.dta)if self.name.data[0].isdigit():raise ValidationError('用户名不能以数字开头')def validate_phone(self, data):"""校验手机号"""phone = data.dataif not re.search(r'^1[35678]\d{9}', phone):  # search返回内容是None或re.Match objectraise ValidationError('手机号码格式错误!')

FlaskForm类中的源码部分
在这里插入图片描述
在这里插入图片描述
Form对象调用validate函数时会自动寻找validate_{name}的方法添加到验证序列,并在原先字段的验证序列验证完毕后执行。

2、视图中使用

这里涉及到了CSRF保护,可查看后面文章

"""
@File: app.py
"""import os
from flask import Flask, render_template, make_response
from flask_wtf import CSRFProtect
from werkzeug.utils import secure_filename
from formtest import UserForm # 导入表单类app = Flask(__name__)# 必须要设置SECRET_KEY这个配置项
# 需要为CSRF保护设置一个密钥,通常情况下,和Flask应用的SECRET_KEY是一样的。
app.config['SECRET_KEY'] = 'hsdkfhksd'app.config['ENV'] = 'development'# 全局使用CSRF保护,为了能够让所有的视图受到CSRF保护,需要扩展 CsrfProtect模块
csrf = CSRFProtect(app=app)@app.route('/home', methods=['GET', 'POST'])
def home():uform = UserForm()if uform.validate_on_submit():"""注意:1、不需要把 request.form 传给 Flask-WTF;Flask-WTF 会自动加载。2、validate_on_submit 将会检查是否是一个 POST 请求并且请求是否有效。"""name = uform.name.datapassword = uform.password.dataphone = uform.phone.datauser_img = uform.user_img.data  # filename = secure_filename(user_img.filename)  # 如果文件名是中文,会只显示后缀,不显示文件名,会有错误,尽量不用中文名BASE_DIR = os.path.dirname(os.path.abspath(__file__))STATIC_DIR = os.path.join(BASE_DIR, 'static')STATIC_DIR = os.path.join(STATIC_DIR, 'upload')user_img.save(os.path.join(STATIC_DIR, filename))return '这是一个post请求,提交成功'return render_template('user.html', uform=uform)if __name__ == '__main__':app.run()

CSRF跨站请求伪造,源于WEB的隐式身份验证机制,WEB的身份验证机制虽然可以保证一个请求来自于某个用户的浏览器,但却无法保证该请求是用户批准发送的。

如果网站没有通过CSRF验证,都会返回400响应

3、模版中的使用

DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>用户页面title><style>p span {color: red;font-size: 14px;}style>head>
<body>
<form action="{{ url_for('home') }}" method="post" enctype="multipart/form-data"><p>{{ uform.csrf_token }}p>  <p>{{ uform.hidden_tag() }}p><p>{{ uform.name.label }}: {{ uform.name }}<span>{% if uform.name.errors %} {{ uform.name.errors.0 }} {% endif %} span>p><p>{{ uform.password.label }}: {{ uform.password }}<span>{% if uform.password.errors %} {{ uform.password.errors.0 }} {% endif %} span>p><p>{{ uform.repassword.label }}: {{ uform.repassword }}<span>{% if uform.repassword.errors %}{{ uform.repassword.errors.0 }}{% endif %} span>p><p>{{ uform.phone.label }}: {{ uform.phone }}<span>{% if uform.phone.errors %}{{ uform.phone.errors.0 }}{% endif %} span>p><p>{{ uform.user_img.label }}: {{ uform.user_img }}<span>{% if uform.user_img.errors %}{{ uform.user_img.errors.0 }}{% endif %} span>p><p><input type="submit" value="提交">p>form>
body>
html>

4、运行后访问查看提示

这里输入框还可以使用bootstrap美化下,这里就不写了…

  1. 这种是自定义的校验报错显示(def validate_name: …)
    在这里插入图片描述

  2. 这种是不符合验证器的提示 (validators)
    在这里插入图片描述

二、总结:

1、视图中使用:

from test import UserForm # 导入定义的类
def xxxx():uform = UserForm()......return render_template('user.html',uform=uform)

2、模板中使用:

<form action="/" method="post">{{ uform.csrf_token }}{{ uform.hidden_tag() }}{{ uform.name }} {{ uform.name.error.0 }}{{ uform.password }} {{ uform.password.error.0 }}<p><input type="submit" value="提交">p>form>

3、验证是否是一个POST,并且是否有效:validate_on_submit()

@app.route('/', methods=['GET','POST'])
def test():uform = UserForm()if uform.validate_on_submit():return '这是一个post请求'return render_template('user.html', uform=uform)

4、在自定义表单类中,还有其他Filed类型、和各种验证

4.1 各种Filed字段类型

class UserForm(FlaskForm):name = StringField(label='用户名',validators=[DataRequired(),  # validators:验证器Length(min=6, max=12)])__all__ = ("BooleanField","TextAreaField","StringField", #  name = StringField( ...... )"PasswordField","FileField","MultipleFileField","HiddenField","SearchField","SubmitField","TelField","URLField","EmailField",
)

4.2 各种的验证:

repassword = PasswordField(label='确认密码',validators=[DataRequired(),Length(min=6, max=12),EqualTo('password', '两次密码不一致')])__all__ = ("DataRequired","data_required","Email","email","EqualTo", # EqualTo('password', '两次密码不一致')"equal_to","IPAddress","ip_address","InputRequired","input_required","Length","length","NumberRange","number_range","Optional","optional","Regexp","regexp","URL","url","AnyOf","any_of","NoneOf","none_of","MacAddress","mac_address","UUID","ValidationError","StopValidation",
)


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部