flask-admin章节五:wtforms FormField超级炫酷使用

1. 概述

查看wtforms代码树fields目录的core.py,会发现在文件开头有这样的语句:

__all__ = (
    ‘BooleanField‘, ‘DecimalField‘, ‘DateField‘, ‘DateTimeField‘, ‘FieldList‘,
    ‘FloatField‘, ‘FormField‘, ‘IntegerField‘, ‘RadioField‘, ‘SelectField‘,
    ‘SelectMultipleField‘, ‘StringField‘,
)

这个表示当前文件在被Import的时候,能够导入的所有方法。上面的这些,除了FieldListFormField这两个表单字段我们平时使用得比较少以外,

其他的我们或多或少都使用过了。而且通常情况下,上面的那些基本的字段已经完全符合我们要求了,除非特殊情况,否则,我们根本没有机会使用到。

关于FormField的使用,估计大家在使用的时候就挺郁闷的。要么就是报错,要么就是渲染出来的页面出现格式问题,根本没法使用。看官网或许帮助不大,

查找中文资料又很少有帮助的,所以就会很困惑。

不过,我最近遇到的一个问题发现用FormField非常的炫酷,而且特别特别有意思。

2. 遇到的问题

最近遇到日常工单系统,大概有13中常规的工单,每种都是不一样的表单。表单创建之后还有对应List、Get以及处理。所以后面大概有30中不同的视图。

如果像之前那种方式,每个表单对应一个HTML,那样会导致页面太多。

另外就是,主页面空间有限,不能让这些表单页面堆积在一起。所以,还是希望这13种表单服用同一个页面,根据用户选择的类型的不同来做不同的展示。

但是,怎样把这13种表单融合在一个HTML文件中,并且不影响到每个表单每个字段的检查。

这块可能要多说下,大家知道我们在使用wtforms Form表单元类派生出自己的表单类的时候,可能对一些必须的字段定义些validator方法,这样在

用户提交表单的时候wtforms自身为我们做了对应的检查。

很显然,我们在做到这点肯定是使用某种隐藏继续,在需要显示的时候才显示对应的页面,其他情况下都是隐藏的。但是,这块又有一个问题就是,

如果隐藏了,哪些隐藏了的定义了validator的表单字段会在表单提交之后直接报错。

解决了这些问题,还有一个问题就是查看页面详情,用户创建一个表单,期待的时候查看详情也看到这块的内容,而不希望看到其他的表单。所以,

这块又需要对应13种不同的页面来展示不同的表单类型的数据。这块能不能用一种更优雅的方式解决?

概括下遇到的问题,大致如下:

  1.  需要展示的表单类型过多,而且后面可能会有新的需求加入,所以需要尽可能的简洁以及可扩展的方式来呈现表单,尽可能把所有表单结构放在一个页面中。
  2. 为了可扩展性,表单类需要继承自wtforms Form类,但是如何确保隐藏的表单中必选字段对当前表单的影响。
  3. 给用户展示对应创建的表单时,能否用一种通用的方式来展示这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. 小结

当使用一种方法复杂到想让你放弃的时候,一定要坚持,因为一定还有其他路要走。因为,你可能之前走错了方向,换个角度思考,你会获得很多意想不到的收获。

时间: 2024-10-12 11:49:39

flask-admin章节五:wtforms FormField超级炫酷使用的相关文章

流量水波浪效果,超级炫酷暖人

流量水波浪效果,超级炫酷暖人 只有效果,大家择善而从.好看的给点个赞就好了 下载地址:http://www.devstore.cn/code/info/801.html 运行截图: 热门源码下载: 高仿京东商城 Android快速开发不可或缺的11个工具类 Android快速开发框架LoonAndroid Android应用源码比较不错的新闻客户端 版权声明:本文为博主原创文章,未经博主允许不得转载.

流量水波浪效果,超级炫酷暖

流量水波浪效果,超级炫酷暖人 只有效果,大家择善而从.好看的给点个赞就好了 下载地址:http://www.devstore.cn/code/info/801.html 运行截图:

超级炫酷的HTML5互动式程序员求职简历

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Typ

前端交互开发微体验--总结了一些国内外炫酷的网站

前端交互开发微体验 关于首屏灵动小效果,微交互提升页面生机: 一.关于首屏视频播放 http://designmodo.com/startup/ 感官体验:科技感,高大上,酷 综合评价:如页面请求不多且视频占空小的情况下使用.一般为首屏轮播图的情况下使用,前两张轮播为图片,最后为视频,多给视频一些加载时间.还有就是非首屏使用. 推荐指数:★★★☆☆     二.Hover时实现图片随着鼠标方向而变动 http://atieva.com/ https://labs.invisionapp.com/

Flask实例教程五

一:Flask中的g对象 Flask中的g对象是个很好的东西,主要用于在一个请求的过程中共享数据.可以随意给g对象添加属性来保存数据,非常的方便,下面的代码是一个使用g对象的例子.下面的这个例子会使用random随机产生一个0~9的整数,并使用g.x保存并记录debug日志: # encoding=utf-8 from flask import Flask from flask import g import random app = Flask(__name__) @app.before_re

一款炫酷Loading动画--加载成功

简介 昨天在简书上看到一篇文章,介绍了一个加载动画的实现过程 一款Loading动画的实现思路(一) 只可惜原动画是IOS上制作的,而看了一下,作者的实现思路比较复杂,于是趁着空闲写了一个Android版本,这篇文章将给大家介绍一下实现过程. 首先让我们来看一下动画效果 动画结构分析 从上面的gif图中可以看到,这个加载动画有成功,失败两种状态,由于Gif速度比较快,我们再来分别看一张慢图 1.成功状态加载动画 成功动画的状态转移描述如下: 1.加载过程,画蓝色圆环,当进度为100%时,圆环完成

[智能硬件] 3、三分钟看懂智能硬件原理——简易智能手环制作教程(包括炫酷手机客户端开发)

首先恭喜大家挺过了测试二!为什么说“挺”呢?因为测试二的难度和测试一相比有一个比较大的跳跃:首先测试一仅仅利用现有硬件模块稍加改造而DIY一个蓝牙防丢器,而测试二则要求大家具有从脑袋里的一个想法到一个全新的小设备的实现的全部能力,显然该过程不是连几根线那么简单:其次测试一对蓝牙的使用仅限于信号搜索层面,而测试二一下子深入到可靠通信的层面了,其难度可想而知:最后在测试二中客户端的设计中复杂的状态转换过程,以及嵌入式编程时需要对所使用的硬件作细致的分析,都构成了对前期基础没打牢的同学一种挑战.不过好

7款纯CSS3实现的炫酷动画应用

1.纯CSS3实现人物摇头动画 这次我们要来分享一款超级可爱的纯CSS3人物摇头动画,初始化的时候人物的各个部位是利用CSS3动画效果拼接而成,接下来就是人物听音乐的场景,一边听音乐一边摇着脑袋,十分陶醉的样子,周围还会出现跳动的音符动画. 在线演示 源码下载 2.CSS3 Loading进度条加载动画特效 3款绚丽风格 今天我要分享一款更加炫酷的CSS3进度条加载动画特效,该动画特效有3个不同的风格,注意,IE6,7,8是不支持该进度条动画的. 在线演示 源码下载 3.纯CSS3实现云雾缭绕动

这样的少年“黑客”,一点也不“炫酷”

少年"黑客",一点也不"炫酷".随着计算机和互联网的普及,许多青少年通过学习掌握了较高水准的电脑技术.掌握一技之长固然可喜,但在司法实践中,却出现了一些利用自身电脑技术实施网络犯罪的犯罪嫌疑人.他们多是未成年人,他们都有一个共同的爱好:攻击正常网络,人称"黑客".那么,这些青少年为什么热衷于当"黑客"?网络"黑客"究竟涉及哪些法律问题呢? 经典案例 1.少年"黑客" 组团侵入银行金融网络