python flask基础总结 表单

Source

在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
我将第一时间删除并道歉 谢谢 !