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 炫酷动画资源 @荧星诉语 收集整理了主流炫酷动画框 ...
随机推荐
- publish/subscribe
Pub/Sub功能 Pub/Sub功能(means Publish, Subscribe)即发布及订阅功能.基于事件的系统中,Pub/Sub是目前广泛使用的通信模型,它采用事件作为基本的通信机制,提供 ...
- IS A 和 HAS A的区别
IS A:一般是用作继承或者接口类.比如:中国人和外国人都是人,重点在:是一个... . HAS A:一般用作对象和他的成员的从属关系.比如:中国人和外国人都有眼睛.耳朵.嘴巴.重点在:有一个... ...
- [转载]Average Manager vs. Great Manager Explained in 10 sketches
Assigning Tasks Delivering News Conducting 1:1s Giving Feedback Dealing with Turbule ...
- axis 理解
前言 使用numpy sum(a,axis=0)的时候,对axis参数比较费解,和直觉不太一样,故此记录 b = np.arange(12).reshape(3,4) b array([[ 0, 1, ...
- python学习(解析python官网会议安排)
在学习python的过程中,做练习,解析https://www.python.org/events/python-events/ HTML文件,输出Python官网发布的会议时间.名称和地点. 对ht ...
- CSS中浏览器开发商特定的CSS属性
浏览器制造商(像Microsoft.Mozilla等,还有WebKit的后台人员等)通常会为他们的浏览器增加新的功能来测试新的特性, 或者实现一直在考虑但还没有得到标准组织批准的CSS扩展.在这些情况 ...
- 构建Maven聚合工程
最近,准备构建一个Maven的项目,基于模块化的结构思想,决定使用Maven的聚合工程进行构建. 环境准备: (1)eclipse 这里推荐使用spring封装的eclipse(即STS) ,STS中 ...
- sql server之数据库语句优化
三.只返回需要的数据 返回数据到客户端至少需要数据库提取数据.网络传输数据.客户端接收数据以及客户端处理数据等环节,如果返回不需要的数据,就会增加服务器.网络和客户端的无效劳动,其害处是显而易见的,避 ...
- 干货 | Docker文件系统的分层与隔离
现在就开始今天的分享~ M老师:docker 的很多特性都表现在它所使用的文件系统上,比如大家都知道docker的文件系统是分层的,所以它可以快速迭代,可以回滚.这个回滚机制跟github很像,每次提 ...
- 【css3】浏览器内核及其兼容性
浏览器内核分类如下: 1.Webkit内核: 使用此引擎内核的浏览器有:Safari(包括移动版和桌面版).Chrome.其私有属性的前缀是-webkit-. 2.Gecko内核: 使用此引擎内核的浏 ...