flask-admin章节五:wtforms FormField超级炫酷使用
1. 概述
查看wtforms代码树fields目录的core.py,会发现在文件开头有这样的语句:
__all__ = (
'BooleanField', 'DecimalField', 'DateField', 'DateTimeField', 'FieldList',
'FloatField', 'FormField', 'IntegerField', 'RadioField', 'SelectField',
'SelectMultipleField', 'StringField',
)
这个表示当前文件在被Import的时候,能够导入的所有方法。上面的这些,除了FieldList和FormField这两个表单字段我们平时使用得比较少以外,
其他的我们或多或少都使用过了。而且通常情况下,上面的那些基本的字段已经完全符合我们要求了,除非特殊情况,否则,我们根本没有机会使用到。
关于FormField的使用,估计大家在使用的时候就挺郁闷的。要么就是报错,要么就是渲染出来的页面出现格式问题,根本没法使用。看官网或许帮助不大,
查找中文资料又很少有帮助的,所以就会很困惑。
不过,我最近遇到的一个问题发现用FormField非常的炫酷,而且特别特别有意思。
2. 遇到的问题
最近遇到日常工单系统,大概有13中常规的工单,每种都是不一样的表单。表单创建之后还有对应List、Get以及处理。所以后面大概有30中不同的视图。
如果像之前那种方式,每个表单对应一个HTML,那样会导致页面太多。
另外就是,主页面空间有限,不能让这些表单页面堆积在一起。所以,还是希望这13种表单服用同一个页面,根据用户选择的类型的不同来做不同的展示。
但是,怎样把这13种表单融合在一个HTML文件中,并且不影响到每个表单每个字段的检查。
这块可能要多说下,大家知道我们在使用wtforms Form表单元类派生出自己的表单类的时候,可能对一些必须的字段定义些validator方法,这样在
用户提交表单的时候wtforms自身为我们做了对应的检查。
很显然,我们在做到这点肯定是使用某种隐藏继续,在需要显示的时候才显示对应的页面,其他情况下都是隐藏的。但是,这块又有一个问题就是,
如果隐藏了,哪些隐藏了的定义了validator的表单字段会在表单提交之后直接报错。
解决了这些问题,还有一个问题就是查看页面详情,用户创建一个表单,期待的时候查看详情也看到这块的内容,而不希望看到其他的表单。所以,
这块又需要对应13种不同的页面来展示不同的表单类型的数据。这块能不能用一种更优雅的方式解决?
概括下遇到的问题,大致如下:
- 需要展示的表单类型过多,而且后面可能会有新的需求加入,所以需要尽可能的简洁以及可扩展的方式来呈现表单,尽可能把所有表单结构放在一个页面中。
- 为了可扩展性,表单类需要继承自wtforms Form类,但是如何确保隐藏的表单中必选字段对当前表单的影响。
- 给用户展示对应创建的表单时,能否用一种通用的方式来展示这13种字段完全不太相同的表单结构,并且代码尽可能具有良好的可扩展性。
3. 大致的解法
由于现在比较晚,所以就不给出详细的解决方案,这块会大致讲下解决方法。不过,相信大家能够从中找到灵感。
针对问题1:
使用wtforms 的FormField,对13种不同方格的表单,创建13种派生自wtforms Form基类的派生类。定义一个功能类,功能类中有13个字段都是FormField类型,
分别对应这13个表单结构。这样就能够做到对单个表单结构的精确控制,即使某个表单内容做了更改也不会影响到页面的布局以及其他模块。
页面的显示,需要重构flask admin系统默认模板admin/file/form.html的内容。具体,对于整个表单调用lib.render_form_fields(form),改为是
对每个表单结构调用lib.render_form_fields(form.XXX_field)。
这样,能够确保渲染出来的FormField字段不会出现格式有问题或者乱码。
针对问题2:
重载派生类表单的validate方法,这块有些技巧,具体可以看下我这块使用的代码:
def validate(self):
monitor_type = self.monitor_type.data
hidden_field_val = str(monitor_type.get('hidden_field', '')) fields = self._fields extra = {}
success = True
for name, field in iteritems(fields):
if name == hidden_field_val:
for _name, _field in iteritems(field._fields):
if not _field.validate(field._fields):
success = False
return success
这块有个技巧,就是在表单中使用隐藏表单来表征当前用户选择的表单类型。这样我们在后端做验证的时候,只
针对当前表单元素做验证,而不是表单功能类的13中表单结构。这样,隐藏的表单中的必选字段就不会影响到当前表单,因为我们只会检查当前显示表单的结构。
上述接粗的代码就是取出隐藏的表单字段的值。不过有一点,由于隐藏表单字段的值是不能用户输入的,只能我们自己用jQuery代码对它进行设置。
这样,这块的问题就解决了。
针对问题3:
这块有个比较有意思的技巧,定义数据库表结构的时候要尽可能的与表单结构无关,这样的话可扩展性更好些。否则,一个是表结构字段太多,太庞大了,
另外就是可扩展性不太好。所以,我这块是使用data字段直接表征整个表单所有数据,每次提交表单的时候,直接获取表单的字典结构:
这块使用了表单的data属性,data属性会直接返回一个字典结构。我们在存储到数据库中直接使用json.dumps(form.data),把表单值序列化成字符串并存到数据库表结构data
字段中。用户读取的时候,在把对应字段json.loads回来,并展示给用户就可以了。
如何给用户展示的时候,不需要定义很多HTML页面,而只使用一个,这块的关键是巧用Form类,我们可以根据表单类型获取到对应的表单派生类,并使用它来定义表单对象,
这块可以使用预定义的map就可以了,而且可扩展性非常好。
定义好表单对象之后,从数据库中load数据,把data字段的值json化之后传给表单。然后,我们直接使用admin/file/form.html 模板渲染页面问题就完全解决了。
4. 小结
当使用一种方法复杂到想让你放弃的时候,一定要坚持,因为一定还有其他路要走。因为,你可能之前走错了方向,换个角度思考,你会获得很多意想不到的收获。
flask-admin章节五:wtforms FormField超级炫酷使用的更多相关文章
- 一款超级炫酷的编辑代码的插件 Power Mode
今天偶尔发现了一款比较炫酷的插件,想让你们看看效果 打代码的时候会有非常炫酷的效果哟 因为我用的编辑器是VScode,所以我也只搞了搞VSCode中使用Power Mode的方法,如果你用的是别的编辑 ...
- eclipse在线安装超级炫酷黑色主题
Darkest Dark Theme插件: 点击菜单栏 Help --> Eclipse Marketplace,输出Darkest Dark Theme进行搜索,如下图: 本主题有17套编辑器 ...
- flask admin学习记录
flask admin是flask框架中一个非常好用的后台管理框架,但是由于文档内容太少,经常遇到问题无法解决,这里记录一下 一简单的使用 from flask import Flask from f ...
- Android高级控件(四)——VideoView 实现引导页播放视频欢迎效果,超级简单却十分的炫酷
Android高级控件(四)--VideoView 实现引导页播放视频欢迎效果,超级简单却十分的炫酷 是不是感觉QQ空间什么的每次新版本更新那炫炫的引导页就特别的激动,哈哈,其实他实现起来真的很简单很 ...
- Flask框架(五) —— session源码分析
Flask框架(五) —— session源码分析 目录 session源码分析 1.请求来了,执行__call__方法 2.__call__方法 3.调用__call__方法 3.1.ctx = s ...
- Flask admin Flask login 整合模板
项目地址: https://github.com/WES6/supflask Flask admin 官方文档: https://flask-admin.readthedocs.io/en/lates ...
- 数据可视化之 图表篇(五) PowerBI图表不够炫酷?来看看这个
现在这个大数据时代,每时每刻.各行各业都在产生多种多样的海量数据,如何简单高效的来理解.挖掘这些数据,发现背后的见解就非常重要. 本文介绍这个图表就可以帮你快速发现海量数据背后的见解,微软研究院打造的 ...
- 再见丑陋的 SwaggerUI,这款开源的API文档生成神器界面更炫酷,逼格更高!
一般在使用 Spring Boot 开发前后端分离项目的时候,都会用到 Swagger.Swagger 是一个规范和完整的框架,用于生成.描述.调试和可视化 RESTful 风格的 Web API 服 ...
- FIR.im Weekly - 让炫酷 UI 为 APP 增色
上周我看到一些不错的设计分享,挑选了几个比较全的 GitHub 资源推荐给大家.此外,还精选了一些实用的 iOS,Android 干货文章. iOS 炫酷动画资源 @荧星诉语 收集整理了主流炫酷动画框 ...
随机推荐
- MySQL 对于千万级的大表要怎么优化?
作者:哈哈链接:https://www.zhihu.com/question/19719997/answer/81930332来源:知乎著作权归作者所有,转载请联系作者获得授权. 第一优化你的sql和 ...
- 28. Red Hat Linux安装Vmware Tools
在VMware虚拟机中安装好了VMware Tools,才能实现主机与虚拟机之间的文件共享,同时可支持自由拖拽的功能,鼠标也可在虚拟机与主机之前自由移动(而不再用按ctrl+alT释放),而且还可以令 ...
- java守护线程的理解
package daemonThread; /*setDaemon(true)方法将线程设置为守护线程,线程的Daemon默认值为false * 只要当前JVM实例中存在任何一个非守护线程没有结束,守 ...
- php面试题目
PHP测试小例 1. 禁用COOKIE 后 SEESION 还能用吗? Cookie 是保存在浏览器 1.cookie是保存在本地的,而seesion是保存在服务器上的.所以两者没有直接的关系,禁用 ...
- java的继承和重写
继承是面向对象最显著的一个特性.继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力.[1] Java继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以 ...
- Python:关于字典的相关操作
>>> people = {"Tom":170, "Jack":175, "Kite":160, "White& ...
- Topcoder几例C++字符串应用
本文写于9月初,是利用Topcoder准备应聘时的机试环节临时补习的C++的一部分内容.签约之后,没有再进行练习,此文暂告一段落. 换句话说,就是本文太监了,一直做草稿看着别扭,删掉又觉得可惜,索性发 ...
- ng-style 的坑 - 对性能的影响
本文地址:http://www.cnblogs.com/jying/p/5633203.html 熟悉 angular 的前端对ng-style 一定不陌生,这个家伙可以绑定一个函数,使得我们可以在函 ...
- ubuntu 安装 git & smartgit
1. 安装 git # sudo apt-get update# sudo apt-get install git 2. 配置 # git config --global user.name &q ...
- const 限定符
1.定义const对象 const限定符把一个对象转换成一个常量 const int Bufsize = 512; 定义Bufsize 为常量并初始化为512.变量Bufsize仍然是一个左值,但是不 ...