flask 利用flask_wtf扩展 创建web表单
在Flask中,为了处理web表单,我们一般使用Flask-WTF扩展,它封装了WTForms,并且它有验证表单数据的功能
- 创建语句格式: startTime = DateTimeField('计划开始时间', validators=[DataRequired('不可为空'),EqualTo('nowTime',message='两次事件必须一致')],format='%Y/%m/%d %H:%M:%S' render_kw={'placeholder':'2018-06-03 00:00:00', 'id': 'rz1','autocomplete': "off"}
- html效果:
<label>计划开始时间</label>
<input autocomplete="off" class="form-control" id="rz1" name="startTime" placeholder="2018-06-03 00:00:00" required="" type="text" value="">
3. 页面展示效果:

解析:
- DataTimeField是从wtforms包导入的字段类 from wtfms import SelectField, StringField, SubmitField, TextField, DateTimeField, FileField。。。
- '计划开始时间'是input标签的lable
- validators是验证器,验证输入值的合法性,以列表的形式封装各种验证函数,验证函数由wtforms.validators导入:from wtforms.validators import DataRequired
- format指定展示格式
- render_kw以字典的形式存放input标签的各种属性
form.py文件在项目中的位置:与逻辑层同级,即与view.py同级,以便于不同的功能块放不同的form表单
项目效果: 三个文件依次是创建蓝图 创建form表单 逻辑(视图)函数

创建表单部分代码案例:
from flask_wtf import Form
from wtforms import SelectField, StringField, SubmitField, TextField, DateTimeField, FileField, SelectMultipleField, TextAreaField, HiddenField
from wtforms.validators import DataRequired class TaskinfoAdd(Form):
taskName = StringField('任务名称:', [DataRequired('任务名称不能为空')], render_kw={'placeholder': '任务名称', 'autocomplete': 'off'})
taskInfo = TextAreaField('详情描述:', render_kw={'placeholder': '任务描述...', 'autocomplete': 'off'})
urgentId = SelectField('紧急程度:', validators=[DataRequired('请选择紧急程度')], coerce=int, render_kw={'style': 'width:110px'})
resPeople = StringField('责任人:', [DataRequired('责任人不能为空')], render_kw={'class': 'res-people', 'placeholder': '责任人', 'style': 'width:110px', 'data-toggle':"modal", 'data-target':"#myModal2"})
exePeople = StringField('参与人(多选):', render_kw={'class': 'exe-people', 'placeholder': '参与人(多选)', 'style': 'width:300px'})
sharePeople = StringField('共享人(多选):', render_kw={'placeholder': '共享人(多选)', 'style': 'width:300px'})
startTime = DateTimeField('计划开始时间:', [DataRequired('开始时间不能为空')], format='%Y-%m-%d %H:%M:%S', render_kw={'placeholder':'2018-06-03 00:00:00', 'id': 'rz1', 'class': 'form-control calendar-control', 'autocomplete': "off"})
endTime = DateTimeField('计划完成时间:', [DataRequired('完成时间不能为空')], format='%Y-%m-%d %H:%M:%S', render_kw={'placeholder':'2019-06-06 00:00:00', 'id': 'rz2', 'class': 'form-control calendar-control', 'autocomplete': 'off'})
workTime = StringField('计划工时(分钟):', [DataRequired('工时不能为空')], render_kw={'placeholder': ''}) loadFile = FileField('附件', render_kw={'multiple': 'multiple'})
submit = SubmitField('保存') class TaskinfoEdit(Form):
taskName = StringField('任务名称:', [DataRequired('任务名称不能为空')])
taskInfo = TextAreaField('详情描述:', render_kw={'placeholder': '任务描述...', 'autocomplete': 'off'})
urgentId = SelectField('紧急程度:', validators=[DataRequired('不可为空')], coerce=int, render_kw={'style': 'width:135px; display:inline-block'})
resPeople = StringField('责任人:', [DataRequired('责任人不能为空')], render_kw={'style': 'width:150px; display:inline-block'})
advanceId = SelectField('进 度:', coerce=int, render_kw={'placehoder': '50%', 'style': 'width:153px; display:inline-block'})
workTime = StringField('计划工时(分钟):', [DataRequired('工时不能为空')], render_kw={'style': 'width:100px; display: inline-block'})
exePeople = StringField('参与人:', render_kw={'style': 'width:220px; display: inline-block'})
sharePeopleTo = StringField('共享人:', render_kw={'style': 'width:220px; display: inline-block'}) loadFile = FileField('上传附件:', render_kw={'multiple': 'multiple'})
download = StringField('下载附件:', render_kw={'placehoder': '无附件', 'style': 'background: white; height:23px; display: inline-block'}, id='download')
reason = StringField('超期原因:', render_kw={'placeholder': '超期原因...', 'autocomplete': 'off'})
submit = SubmitField('提交')
form.py
flask接收后端处理:
@task_mgm.route('/taskinfo_add', methods=['GET', 'POST'])
@login_required
def taskinfo_add_fun():
form1 = TaskinfoAdd()
form1.urgentId.choices = [(urgences.id, urgences.urgentName) for urgences in Urgence.query.all()]
if form1.validate_on_submit():
task = MgmTask(taskName=form1.taskName.data, urgentId=form1.urgentId.data, resPeople=form1.resPeople.data,
exePeople=form1.exePeople.data, sharePeopleTo=form1.sharePeople.data, startTime=form1.startTime.data,
endTime=form1.endTime.data, workTime=form1.workTime.data, taskInfo=form1.taskInfo.data,
createPeople=current_user.name)
# 替换汉语逗号
task.sharePeopleTo.replace(',', ',')
task.resPeople.replace(',', ',')
task.exePeople.replace(',', ',')
# 保存上传的文档
upload(form1, task)
try:
db.session.add(task)
db.session.commit()
except Exception as e:
logging.error(e)
return redirect(url_for('task_mgm.taskinfo_add_fun'))
return render_template('/task_mgm/taskinfo_mine.html', form1=form1, name=current_user.name, grade=current_user.grade)
# 编辑任务
@task_mgm.route('/taskinfo_editID=<int:num>', methods=['GET', 'POST'])
@login_required
def taskinfo_edit_fun(num):
task = MgmTask.query.get(num)
pageType = request.values.get('pageType')
formEdit = TaskinfoEdit(obj=task)
formEdit.urgentId.choices = [(urgences.id, urgences.urgentName) for urgences in Urgence.query.all()]
formEdit.advanceId.choices = [(advances.id, advances.name) for advances in Advance.query.all()]
if task.fileName:
formEdit.download.data = task.fileName
if formEdit.validate_on_submit():
formEdit.populate_obj(task) # 重新填充表单
if formEdit.advanceId.data == 5:
task.finishTime = datetime.now()
upload(formEdit, task)
try:
db.session.add(task)
db.session.commit()
except Exception as e:
logging.error(e)
page = request.args.get('page', 1, type=int)
pagination = Comment.query.filter(Comment.taskId == num).order_by(Comment.createTime.desc()).paginate(
page, per_page=225, error_out=False)
comments = pagination.items
return render_template('/task_mgm/taskinfo_edit.html', formEdit=formEdit, header='编辑任务', comments=comments, pagination=pagination, pageType=pageType, name=current_user.name, grade=current_user.grade)
view.py
html前端可以继承bootstrap的wtf.html 也可以直接写:
- 继承:
{% import "bootstrap/wtf.html" as wtf %}
<div class="modal-body" style="margin-top: 20px">{{ wtf.quick_form(form1, form_type='horizontal', horizontal_columns=('md', 3, 8)) }}
<button type="button" class="btn btn-default" data-dismiss="modal"
style="position:relative; margin-left: 460px; bottom:49px;">关闭
</button>
</div>
- 不继承
<form method="post">
{#设置csrf_token#}
{{ form.csrf_token() }}
{{ form.username.label }}{{ form.username }}<br>
{{ form.password.label }}{{ form.password }}<br>
{{ form.password2.label }}{{ form.password2 }}<br>
...
{{ form.input }}<br>
</form>
WTForms支持的HTML标准字段:
| 字段对象 | 说明 |
|---|---|
| StringField | 文本字段 |
| TextAreaField | 多行文本字段 |
| PasswordField | 密码文本字段 |
| HiddenField | 隐藏文件字段 |
| DateField | 文本字段,值为 datetime.date 文本格式 |
| DateTimeField | 文本字段,值为 datetime.datetime 文本格式 |
| IntegerField | 文本字段,值为整数 |
| DecimalField | 文本字段,值为decimal.Decimal |
| FloatField | 文本字段,值为浮点数 |
| BooleanField | 复选框,值为True 和 False |
| RadioField | 一组单选框 |
| SelectField | 下拉列表 |
| SelectMutipleField | 下拉列表,可选择多个值 |
| FileField | 文件上传字段 |
| SubmitField | 表单提交按钮 |
| FormField | 把表单作为字段嵌入另一个表单 |
| FieldList | 一组指定类型的字段 |
WTForms常用验证函数:
| 验证函数 | 说明 |
|---|---|
| DataRequired | 确保字段中有数据 |
| EqualTo | 比较两个字段的值,常用于比较两次密码输入 |
| Length | 验证输入的字符串长度 |
| NumberRange | 验证输入的值在数字范围内 |
| URL | 验证URL |
| AnyOf | 验证输入值在可选列表中 |
| NoneOf | 验证输入值不在可选列表中 |
提示:
使用Flask-WTF需要配置参数SECRET_KEY。
CSRF_ENABLED是为了CSRF(跨站请求伪造)保护。 SECRET_KEY用来生成加密令牌,当CSRF激活的时候,该设置会根据设置的密匙生成加密令牌
flask 利用flask_wtf扩展 创建web表单的更多相关文章
- Flask之模板web表单
3.3 Web表单: web表单是web应用程序的基本功能. 它是HTML页面中负责数据采集的部件.表单有三个部分组成:表单标签.表单域.表单按钮.表单允许用户输入数据,负责HTML页面数据采集,通过 ...
- Flask 教程 第三章:Web表单
本文翻译自 The Flask Mega-Tutorial Part III: Web Forms 这是Flask Mega-Tutorial系列的第三部分,我将告诉你如何使用Web表单. 在第二章中 ...
- Flask学习 三 web表单
web表单 pip install flask-wtf 实现csrf保护 app.config['SECRET_KEY']='hard to guess string' # 可以用来存储框架,扩展,程 ...
- Flask开发系列之Web表单
Flask开发系列之Web表单 简单示例 from flask import Flask, request, render_template app = Flask(__name__) @app.ro ...
- Flask学习之三 web表单
本部分Miguel Grinberg教程的翻译地址:http://www.pythondoc.com/flask-mega-tutorial/webforms.html 开源中国的:http://ww ...
- Flask:web表单
客户端发送的所有通过POST发出的请求信息都可以通过request.form获取.但是如果我们要生成表单的HTML代码和验证提交的表单数据那么就需要采用另外的方法.Flask-WTF扩展可以把处理we ...
- Flask:处理Web表单
尽管 Flask 的请求对象提供的信息足以处理 Web 表单,但有些任务很单调,而且要重复操作.比如,生成表单的 HTML 代码和验证提交的表单数据.Flask-WTF 扩展可以把处理 Web 表单的 ...
- Flask Web Development —— Web表单(上)
Flask-WTF扩展使得处理web表单能获得更愉快的体验.该扩展是一个封装了与框架无关的WTForms包的Flask集成. Flask-WTF和它的依赖集可以通过pip来安装: (venv) $ p ...
- Flask教程 —— Web表单(上)
第二章中介绍的request对象公开了所有客户端发送的请求信息.特别是request.form可以访问POST请求提交的表单数据. 尽管Flask的request对象提供的支持足以处理web表单,但依 ...
随机推荐
- WebApiClient的JsonPatch局部更新
1. 文章目的 随着WebApiClient的不断完善,越来越多开发者选择WebApiClient替换原生的HttpClient,本文将介绍使用WebApiClient来完成JsonPatch提交的新 ...
- 【我们一起写框架】MVVM的WPF框架(三)—数据控件
这世上,没人能一次性写出完美无缺的框架:因为,任何一个框架都需要项目的淬炼,然后才能升华,趋近完美. 所以,框架是个反复修改的东西,最终形成的东西. 如果你学了一点技术,觉得自己可以写出框架了,觉得自 ...
- 解决Windows对JDK默认版本切换问题
注意修改path路径,或者修改控制面板下的java控制面板并不有效,原因是由于在WINDOWS\System32环境变量中的优先级高于JAVA_HOME设置的环境变量优先级,故如果只修改环境变量JAV ...
- C# 2进制、8进制、10进制、16进制...各种进制间的转换(三) 数值运算和位运算
一.数值运算 各进制的数值计算很简单,把各进制数转换成 十进制数进行计算,然后再转换成原类型即可. 举例 :二进制之间的加法 /// <summary> /// 二进制之间的加法 /// ...
- 我的Spring Boot学习记录(一):自动配置的大致调用过程
1. 背景 Spring Boot通过包管理工具引入starter包就可以轻松使用,省去了配置的繁琐工作,这里简要的通过个人的理解说下Spring Boot启动过程中如何去自动加载配置. 本文中使用的 ...
- MongoDB学习(配置用户账户和访问控制)
理解admin数据库 安装MongoDB时,会自动创建admin数据库,这是一个特殊的库.有些用户账户角色赋予用户操作多个数据库的权限,而这些用户只能在admin数据库中创建.要创建有权操作所有数据库 ...
- element-tree-grid(表格树)的使用
表格树,element-tree-grid需要单独下载并再配合elementUi里el-table使用. 步骤:1.npm install element-tree-grid --save(下载ele ...
- 一个基于OCV的人肉选取特征点程序
基于OpenCV写了一个交互式获取图片上的人肉选取的特征,并保存到文件的小程序. 典型应用场景:当在一个精度不高的应用需求中,相机分辨率差或者变形严重,某些棋盘点通过代码检测不出,就可以通过手工选取的 ...
- deepin linux 学习笔记(二)——文本编辑器
目录 deepin linux 学习笔记(二)--文本编辑器 前言 nano 小巧的命令行编辑器 通用 编辑 定位 排版 配置 vim 思路独特的超级编辑器 命令模式 插入模式 底线模式(末行模式) ...
- vue 外部字体图标使用,无须绝对路径引入办法
通常外部字体图标都在使用 iconfont ,这种图标在网上搜到一大把都是由于路径问题显示不出来,或者是显示个方块. 最近的项目中也碰到这个坑爸的问题,总结一下解决办法: 和 webpack.conf ...