在web中用户常常要用到登录 注册 找回密码 撰写文章 编辑设置 作为开发我们要了解表单的使用
包括 : 创建表单 验证用户输入的内容 返回错误提示 保存数据 多用户表单
使用模块 WTForm Flask-WTF 和 Flask-CKEditor
WTForms 是定义 验证和处理表单的库
Flask-WTF 继承于WTForms 然后添加一些功能
Flask-CKEdito 富文本编辑器的操作
在html中 定义一个表单可以这样写
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录页面</title>
</head>
<body>
<label for="username">用户名</label><br>
<input type="text" name="username" placeholder="输入你的用户名"><br>
<label for="password">密码</label><br>
<input type="password" name="password" placeholder="请输入你的密码"><br>
<input type="submit" name="submit" value="登录">
</body>
</html>
效果:
而flask中 WTForm也支持类定义表单 然后生成表单 易于重用 而且方便
这里我们使用flask-wtf 因为是WTForm的子类 所以WTForm的功能都可以实现
csrf令牌
首先我们必须要生成一个csrf的令牌 令牌最好写在配置文件中 然后通过app.config[‘SECRET_KEY’]的方法导入
定义表单类
在定义表单类之前 我们先要了解WTForm的常用字段
字段 | 用法 |
---|---|
BooleanField | 布尔类型 值会被处理为True 或者 False |
DateField | 文本字段 值被处理为时间 datetime.date 对象 |
DateTimeField | 文本字段 值被处理为 datetime.datetime 对象 |
FileField | 文件上传字段 用这个字段可以上传文件操作 |
FloatField | 浮点数字段 值会处理为浮点型 |
IntegerField | 整数字段 值会被处理为整型 |
RadioField | 单选按钮 |
SelectField | 下拉列表 |
SelectMultipleField | 多选下拉列表 |
SubmitField | 提交按钮 |
字段常用参数
参数 | 用法 |
---|---|
label | 渲染后后显示在输入字段前的文字 |
render_kw | 设置对应html标签属性 |
validators | 验证器传入方法 |
default | 字段默认值 |
validators参数的验证器
验证器 | 用法 |
---|---|
DateRequired(message=‘验证失败提示’) | 验证数据是否有效 |
Email(message=‘验证失败提示’) | 验证email地址 |
EqualTo(filedname,message=‘验证失败提示’)) | 验证两个字段是否相同 (多用于确认密码) |
InputRequired(message=‘验证失败提示’) | 验证是否有数据 |
Length(最小长度,最大长度message=‘验证失败提示’) | 验证长度是否在给定的有效范围 |
NumberRange(最小长度,最大长度,message=‘验证失败提示’) | 验证数字是否在给定的有效范围 |
Optional(strip_whitespace=True) | 允许输入值为空 并跳过其他验证 |
Regexp(正则表达式,flags=0,message=‘验证失败提示’) | 使用正则表达式验证输入值 |
URL(message=‘验证失败提示’) | 验证url地址 |
AnyOf(给定的范围,message=‘验证失败提示’) | 验证数据是否在给定的范围 |
NoneOf(给定范围,message=‘验证失败提示’) | 验证数据不再给定范围 |
下面定义表单类示例
from wtforms import Form, IntegerField, StringField, BooleanField, SubmitField
from wtforms.validators import DataRequired, Length
class Login(Form):
username = StringField(label='用户名', validators=[DataRequired(), Length(5, 25)],
render_kw={'placeholder': '请输入用户名'})
# username处理为字符串 验证数据是否有效 限制长度为5-25 设置placeholder 属性为 请输入用户名
password = StringField(label='密码', validators=[DataRequired(), Length(6, 64)],
render_kw={'placeholder': '请输入密码'})
# password处理为字符串 验证数据是否有效 限制长度为6-64 设置placeholder 属性为 请输入密码
submit = SubmitField('登录')
# 登录按钮
表单类调用成功后实现的结果和以上用html的方法效果一样
属性方法可以用render_kw 设置字典方式设置属性
还可以使用时传入属性form.username(属性名=属性)
渲染表单
1.调用方法:
可以直接调用方法得出
先实例化表单类 form = Login( )
调用方法 form.username( ) 即可得出相应的html 可用于测试
2.模板中渲染表单
视图函数中 通过渲染 函数 render_template(‘html文件’,form=form) 传入form实例
html 文件中用以下写法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录页面</title>
</head>
<body>
<form method="post">
{{ form.csrf_token }}
{{ form.username.label }}<br>{{ form.username }}<br>
{{ form.password.label }}<br>{{ form.password }}<br>
{{ form.submit }}<br>
</form>
</body>
</html>
视图函数
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired, Length
class Login(FlaskForm):
username = StringField(label='用户名', validators=[DataRequired(), Length(5, 25)],
render_kw={'placeholder': '请输入用户名'})
# username处理为字符串 验证数据是否有效 限制长度为5-25 设置placeholder 属性为 请输入用户名
password = StringField(label='密码', validators=[DataRequired(), Length(6, 64)],
render_kw={'placeholder': '请输入密码'})
# password处理为字符串 验证数据是否有效 限制长度为6-64 设置placeholder 属性为 请输入密码
submit = SubmitField('登录')
# 登录按钮
from flask import Flask, render_template
app = Flask(__name__)
app.secret_key = 'this is key'
@app.route('/')
def login():
form = Login()
return render_template('temp.html',form=form)
app.run(debug=True)
可以在网页127.0.0.1:5000中访问得出表单
上面的form.csrf_token 是为了手动渲染字段 确保表单通过验证 在视图函数中调用 form.hidden_tag()方法渲染表单中所有隐藏的字段
渲染bootstrap风格 因为没有前端的基础 后面去补 这边先照抄
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录页面</title>
</head>
<body>
<form method="post">
{{ form.csrf_token }}
<div class="form-group">
{{ form.username.label }}<br>
{{ form.username(class='form-control') }}
</div>
<div class="form-group">
{{ form.password.label }}<br>
{{ form.password(class='form-control') }}
</div>
{{ form.submit(class='btn btn-primary') }}
</form>
</body>
</html>
处理表单数据
处理表单数据的流程为
1.获取表单数据
2.对表单数据转换
3.验证数据是否符合要求 同时验证CSRF令牌
4. (1)如果验证通过进行下一步操作比如存数据库
(2)如果验证不通过生成错误消息 并在模板中显示错误消息
用代码表示为
1.form = Login( )
2.form.data
3.form.validate( )
4.True : …
False : form.errors
当提交按钮被单击时 flask会创建一个提交表单的HTTP请求 请求中包含字段的数据
提交表单的操作的属性
action : 表单提交时发送的请求url 也就是交给对应的视图函数处理
method : 提交表单的请求方式 默认为get 我们一般设置为post 当使用get请求提交表单时 用户提交表单的数据就会以字符串的方式附加在请求的url中
enctype : 表单数据的编码类型 可以设置为multipart/form-data 纯文本类型为text/plain
验证表单数据
用户在提交表单时 服务器需要验证表单的合法性 flask提供两种验证形式
客户端验证:
把验证方式写入html文件中 比如添加type required min 属性
服务端验证
服务端验证为用户把输入的数据提交到服务端 然后flask对数据进行验证
服务端视图函数验证表单
一般使用 if request.method == “post” and form.validate( ) 此判断请求方式是否为post 并且 验证是否通过
wtform封装了以上方法 可以使用函数 form.validate_on_submit( ) 可以实现以上判断
浏览器操作使用f5刷新 一般会使用上一次的请求方式 我们一般为了防止重复提交表单 要在处理表单后返回一个重定向url 然后实现最后一个请求为get
渲染错误消息
使用form.字段名.errors 返回字段的错误消息列表 可以在html中设置相应的错误提示
{% for message in form.username.errors %}
<small class="error">{{ message }}</small><br>
我们还可以将错误消息自定义 不使用内置的错误消息
以下讲错误消息设置成中文
class BaseForm(FlaskForm):
class Meta: #设置中文 语言
locales = ['zh']
class Login(BaseForm): #表单类继承自BaseForm
username = StringField('用户名',validators=[Dataquired()])
pass
我们也可以将html文件中加入宏 然后使用宏渲染表单 简化操作
表单验证器
wtform 除了内置的验证器 还可以使用自定义验证器
行内验证器
当表单中包含以’validate_字段名’ 开头的函数时 验证字段会自动调用此方法 验证方法接收两个位置参数 依次为form field 前面为字段数据 后面为字段对象
方法:
class Login(FlaskForm)
字段1
字段2
def validate_id(form, field):
if not field.data :
raise ValidationError('请输入数据')
全局验证器
使用环境为创建一个可以重用的通用验证器 自定义函数实现
def have_id(form, field):
if not field.data :
raise ValidationError('请输入数据')
# 在表单类中
class Login(FlaskForm)
id = IntegerField('The Number', validators=[have_id])
在生产中 验证器要实现方便 我们需要使用工厂形式全局验证器
from wtforms.validators import ValidationError
def have_id(message=None):
if message is None:
message = '验证错误的原因'
def have_id(form,field):
if not form.data:
raise ValidationError(message)
return have_id
文件上传
web中 用户不仅仅有提交表单 输入 还需要支持用户上传文件
开发人员需要进行以下操作
- 创建上传表单
- 验证文件类型
- 验证文件大小
- 过滤文件名
创建上传表单的方式和普通方式一样
class Login(FlaskForm):
file = FileField( '文件名' , validators=[FileRequired(), #验证是否有文件
FileAllowed(['jpg', 'jpg','jpeg','png'])])
#验证文件类型
文件上传验证器
验证器 | 使用 |
---|---|
FileRequired | 验证文件是否存在 |
FileAllowed | 验证文件类型 |
通过配置文件选项 app.config[‘MAX_CONTENT_LENGTH’] = 文件大小数字
因为上传的文件容易造成文件名重复 我们可以使用uuid方法给添加一个文件名
Flask-CKEdotor 富文本编辑器
一般用于使用编辑的内容使用
常用配置
配置 | 说明 |
---|---|
CKEDITOR_SEACE_LOCAL | 是否使用本质资源 |
CKEDITOR_PKG_TYPE | CKEditor 包类型 |
CKEDITOR_LANGUAGE | 界面语言 |
CKEDITOR_HRIGHT | 编辑器高度 |
CKEDITOR_WIDTH | 编辑器宽度 |
定义富文本编辑器表单只需要在字段中使用即可
比如
body = CKEditorField('Body', validators=[DataRequired()])
渲染时和正常方式一样 也可以使用基模板 自定义富文本编辑器模板
多按钮提交方式
一般情况下 一个表单不止有一个按钮 有可能为取消 提交 上一步等等
这里我们分为多种情况分析多提交按钮操作
1.单表单 多提交
例如
save = SubmitField('保存') # 保存按钮
publish = SubmitField('提交') # 提交按钮
这里我们只需要判断每一个按钮是否为True或者False 然后判断是否为提交或者保存按钮
2.单页面多表单
单视图函数的处理方式为:
定义多个表单类 然后类1按钮设置为submit1 类2按钮设置为submit2
以此类推然后在视图函数中依次处理
多视图函数的处理方式为:
url 路由地址一样 一个函数处理post 一个函数处理get
或者点击按钮重定向到单独地址 然后定义此视图函数处理bij
以上为表单总结回顾笔记
资料来源于李辉-flask开发实战 若侵权 请联系
qq : 1759435876
微信 : 17711405764
我将第一时间删除并道歉 谢谢 !