Flask+LayUI开发手记(十一):选项集合的数据库扩展类

        条目较少的选项集合,确实可以在程序中直接定义(其实最合适的还是存储在一个分类别的数据库表里),但条目较多的选项集合,或者是复杂的树型结构选项集合,一般都是存储在数据库中的,这样维护起来比较方便,也容易迁移和共享。所以,在完成基础选项集合框架后,考虑应用的方便性,面向数据库存储的选项集合扩展类就成了下一步开发的任务。

        有了基础类做底,这些实现扩展起来也是十分方便。基于数据库存储的类包括两大类型,一种是列表类,这个就是基础选项类的扩展,数据结构没有区别,只是多了选项条目从数据库中装载到内存中的过程,另一种是树型类,它的数据结构比列表类复杂了一些,数据库里也是以父子ID方式存放数据,放在内存里则是一个包括父子ID和名称的字典,依据父子ID关系可以生成与layui-tree组件接口一致的树型结构传送到前端。

        下面这段是列表类的python服务类List_OptionSet,它是基于OptionSet基础类扩展的,所以,相同功能的类函数直接复用基础类。重写的子类函数包括构造函数__init__()和get_dict(),新写的函数包括load()和reload()。可以看出,列表类与基础类的区别是比较小的。

 (注:写到这儿时,发现原来的基础类中有个错误,就是reload()函数也必须在基础类里编写出来,否则如果对基础类选项集合进行重载时,就会出现系统级错误)

#取自数据库表的列表选项集合
class List_OptionSet(OptionSet):def __init__(self,dbclass=None,fdinf=None,n_opt=None,t_opt=None) :super().__init__()self.dbclass = dbclassself.fdinf = fdinfself.opt_name = n_optself.opt_title = t_optif n_opt :sysOptionPool.add_optset(n_opt,self)# 取选项字典def get_dict(self):if (self.opt_dict == None):if self.load(self.dbclass,self.fdinf) == 0:return Nonereturn self.opt_dict# 数据装入函数def load(self,dbclass,fdinf):logging.info('Load Table OptionSet %s....' % self.opt_name)fdkey = fdinf.get('key')fdname = fdinf.get('name')filtstr = fdinf.get('filter')try :rows = db.session.query(dbclass).filter(text(filtstr)).all()opt_info = {}for irow in rows:valkey = getattr(irow,fdkey)valname = getattr(irow,fdname)opt_info[valkey] = valnameself.opt_dict = opt_infoexcept SQLAlchemyError as e:logging.debug('装入选项集合[%s]数据库读取失败!!%s' % (self.opt_name,str(e.orig)))return 0return 1#数据重载函数def reload(self) :rtncode = self.load(self.dbclass,self.fdinf)if rtncode == 0 :return 0if self.opt_name :sysOptionPool.add_optset(self.opt_name,self)return 1

        列表类实现时,重点要强调一下,类实例初始化时并不会从数据库中取数据,而是在第一次使用时,如果判断条目字典为空,才会从数据库中加载条目数据,这是系统中经常用到的方法,因为在系统启动时,所有的选项实例就已经生成了,但大部分的实例在运行时并不会用到,如果这时加载,那会占用较多内存,并且启动时间也会加长。

        上面这个实现在get_dict()中完成,当self.opt_dict为空时调用load函数完成加载。reload()函数的主要用途是将条目数据从数据库重新装载到类实例中。当选项条目被维护后,就会调用此函数完成选项集合的同步。重载是选项集合服务一个路由请求实现,在上一节中有体现。

        下面这段代码是树型选项集合类Tree_OptionSet的实现,它是在列表类的基础上扩展的。可以看出,树型类进行了大量的扩充,几乎所有的函数都进行了重写,并且增加了多个函数。树型选项的存储结构不再是简单的键值对字典,而是一个以ID为键字的复合字典,并为前端提供了列表、映射以及树型等多种格式的数据服务。

##树型的选项集合类    
class Tree_OptionSet(List_OptionSet) :def __init__(self,dbclass=None,fdinf=None,n_opt=None,t_opt=None) :super().__init__()self.dbclass = dbclassself.fdinf = fdinfself.opt_name = n_optself.opt_title = t_optif n_opt :sysOptionPool.add_optset(n_opt,self)# 获取选项名称def get_name(self,id) :dt_id = self.get_dict().get(id)if dt_id == None :return '-'return dt_id.get('name')# 获取选项格式串(废弃保留)def id_format(self,id):dt_id = self.get_dict().get(id)if dt_id == None :return '-'idname = dt_id.get('name')if isinstance(id, str) :return id + '_' + idnameelse :return str(id) + '_' + idname# 获取选项映射def get_map(self):itemlist = {}d_opt = self.get_dict()if (d_opt == None) :return Nonefor (k,v) in d_opt.items():itemlist[k] = v['name']return itemlist# 获取选项列表def get_list(self,**kwargs) :itemlist = []d_opt = self.get_dict()if (d_opt == None) :return Nonefor (k,v) in d_opt.items():item = [k,v['name'],v['pid'],0]itemlist.append(item)f_sort = kwargs.get('sort')if f_sort == None or f_sort == False:return itemlistreturn sorted(itemlist)# 数据装载def load(self,dbclass,fdinf):logging.debug('Load Table Tree Options %s....' % self.opt_name)fdkey = fdinf.get('key')fdname = fdinf.get('name')fdvalue = fdinf.get('value')fdparent = fdinf.get('parent')filtstr = fdinf.get('filter')try :rows = db.session.query(dbclass).filter(text(filtstr)).all()opt_info = {}for irow in rows:valkey = getattr(irow,fdkey)valname = getattr(irow,fdname)valparent = getattr(irow,fdparent)opt_info[valkey] = dict(name=valname,pid=valparent)if (fdvalue != None) :valvalue = getattr(irow,fdvalue)opt_info[valkey]['value'] = valvalueself.opt_dict = opt_infoexcept SQLAlchemyError as e:logging.debug('装入树型选项集合[%s]数据库读取失败!!%s' % (self.opt_name,str(e.orig)))return 0return 1# 获取选项集合def get_option(self,optcat=None) :return self.get_tree()# 获取选项树型def get_tree(self) :item_opt = self.get_list(sort=True)if item_opt == None:return Noneif hasattr(self,'fdinf') :root_id = self.fdinf.get('rootid')else :root_id = 0#logging.debug('item_opt: %s' % item_opt)item_tree = self.build_tree(item_opt,root_id,0)return item_tree# 生成选项树型# 基于Layui-Tree接口格式生成数据def build_tree(self,data,p_id,level=0):tree = []for item in data:if item[2] !=p_id:continuerow = dict(id = item[0], title= item[1], parent_id=item[2],level= level)if level==0:row['spread'] = Truechild = self.build_tree(data, row['id'], level+1)row['children'] = []if child:row['children'] += childtree.append(row)return tree

        通过加载函数load()完成条目字典的原始数据结构加载,其数据结构为{id111:{name:xxx,pid:xxx,value:xxx},id222:{...},...}。之后由原始数据结构为基础,然后通过一系列函数完成数据服务,主要包括:

get_name():根据键值取名称

id_format():生成格式化的选项展示(后台生成展示项时用)

get_map():生成键值map映射表

get_list():生成键值列表

get_tree():生成树型选项集合

get_option():对外提供的统一的选项集合接口

        上述功能实现后,统一选项集合数据服务类就基本完成了。下面是几个具体的选项集合实例。

# 系统用户角色选项处理
optOprRole = List_OptionSet(Role,{'key': 'role_cd','name' : 'rolename','filter' : 'status=0 and roletype=0'},'OprRole')#机构树型选项处理
optBranchTree = Tree_OptionSet(Branchs,{'key': 'id','name' : 'short_name','parent' : 'parent_id','rootid' : 0,'filter' : 'status=0'},'BranchTree')#机构状态
optBranchStatus = OptionSet({0:'正常',1:'停用',9:'废弃'},'BranchStatus')

        前端通过服务请求可以下载选项集合数据,并按个性化的需求对前端组件进行渲染。比如对layui-form中已经有的select、checkbox进行功能增强,也可以自行实现单选树型、多选树型等复合选择域,从而将layui-form的功能再次提升。

        

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/89243.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/89243.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI学习笔记三十二:YOLOv8-CPP-Inference测试(Linux版本)

若该文为原创文章,转载请注明原文出处。主要介绍如何在Linux系统上安装和部署基于YOLOv8的C推理项目一、服务器准备使用AutoDL平台租用服务器AutoDL有git加速,可以自行启用二、环境配件1、检查Opencv版本pkg-config --modversion opencv4如果版本为4.5&a…

113:路径总和 II

题目:给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。叶子节点 是指没有子节点的节点。解答:用 go主要坑有两个,一个是二维结果切片传递用指针,一个…

Perl 数组

Perl 数组 在Perl编程语言中,数组是处理数据的一种强大工具。数组允许我们将多个值存储在单个变量中,从而简化了代码并提高了效率。本文将详细介绍Perl数组的创建、操作、遍历以及一些高级用法。 数组的创建 在Perl中,创建一个数组非常简单。…

优先队列的实现

目录 引言 堆的基本概念与特性 堆的插入与向上调整 堆的删除与向下调整 优先队列的设计思路 模板参数设计 比较器的作用 核心接口实现 push pop top 附录(完整代码) 引言 优先队列(Priority Queue)是一种特殊的队列数据结构,其中每…

现代CSS实战:用变量与嵌套重构可维护的前端样式

现代CSS实战:用变量与嵌套重构可维护的前端样式 引言 在传统CSS开发中,我们常常陷入「样式冗余」与「维护噩梦」的循环: 想调整主题色?得全局搜索所有 #3498db 手动替换,稍有不慎就漏改某个角落; 写嵌套…

DHTMLX Suite 9.2 重磅发布:支持历史记录、类Excel交互、剪贴板、拖放增强等多项升级

全球知名的 JavaScript UI 组件库 DHTMLX Suite 迎来 9.2 新版本!此次更新虽为次版本号,却实质性提升了 Grid 网格组件的交互能力与用户体验,引入了包括历史记录管理、剪贴板操作、数据选择范围管理、Block 区块选择等多项高级模块&#xff0…

深入理解Java中的Map.Entry接口

文章目录深入理解Java中的Map.Entry接口1. 接口定义2. 核心方法解析2.1 基本方法2.2 Java 8新增的静态方法3. 基本使用示例3.1 遍历Map的条目3.2 修改Map中的值3.3 使用比较器排序4. Java 8/9增强特性4.1 与Stream API结合4.2 Java 9的equals和hashCode默认方法5. 实际应用场景…

AI培训学习2

不要打扰用户的习惯,比如APP右下角的我的,放到第一个就不合适 先抄再超 lifeTime value NPS: 评价 Product market 平衡 ARPU: LT活跃时长 游戏中好友的重要性 不花钱存活率很少 如何花钱,1分钱买东西 联影医疗 figma uizard…

npm 安装时候怎么指定某一个子包的版本 overrides

有时候用 npm install 安装的时候会报错,比如 express 包依赖 "escape-html": "^1.0.2" 版本的包,但是因为 escape-html" 升级到 1.0.3 版本了,但是这个版本有问题,导致express 下载不下来。怎么固定下载…

python学智能算法(十九)|SVM基础概念-超平面

引言 前序学习进程中,对向量相关的基本知识进行了学习,链接为: 向量的值和方向 向量点积 在实际的支持向量机算法使用中,最核心的目标是找出可以实现分类的超平面,超平面就是分割的点、线或者面,不要在这个…

python 基于 httpx 的流式请求

文章目录1. 环境介绍2. 同步客户端2.1. 面向过程2.1.1. 流式输出2.1.2. 非流式输出2.2. 面向对象3. 异步客户端3.1. 面向过程3.2. 面向对象3.3. Attempted to call a sync iterator on an async stream.参考:https://www.jb51.net/article/262636.htm次要参考&#…

Python 数据建模与分析项目实战预备 Day 4 - EDA(探索性数据分析)与可视化

✅ 今日目标 使用 Pandas Matplotlib/Seaborn 对简历数据进行探索性分析分析不同字段与目标变量的相关性通过可视化呈现简历筛选的潜在规律🧾 一、建议分析内容 🔹 分类字段分析字段图表建议说明degree柱状图(分组通过率)分析学历…

力扣每日一题--2025.7.17

📚 力扣每日一题–2025.7.17 📚 3202. 找出有效子序列的最大长度 II(中等) 今天我们要解决的是力扣上的第 3202 题——找出有效子序列的最大长度 II。这道题是昨天 3201 题的扩展,需要我们处理更一般化的情况。 ⚠️…

github不能访问怎么办

访问:“github.com”国内多个地点网站测速结果_网站测速 - 站长工具访问“github.global.ssl.fastly.net”国内多个地点网站测速结果_网站测速 - 站长工具复制红框中的ip 打开“C:\Windows\System32\drivers\etc\hosts”文件输入: 20.205.243.166 githu…

【深度学习新浪潮】AI在finTech领域有哪些值得关注的进展?

近年来,AI在金融科技(FinTech)领域的应用呈现爆发式增长,尤其在大模型技术突破和政策支持的双重驱动下,多个关键领域取得了显著进展。以下是值得关注的核心方向及具体案例: 一、大模型技术重塑金融服务范式 以DeepSeek为代表的国产大模型通过开源和低成本部署(本地化成…

【中等】题解力扣22:括号生成

题目详情 数字 n 代表生成括号的对数,设计一个函数生成所有可能的并且有效的括号组合。 示例 1: 输入:n 3 输出:[“((()))”,“(()())”,“(())()”,“()(())”,“()()()”] 示例 2: 输入:n 1 输出&#…

【JEECG 组件扩展】JSwitch开关组件扩展单个多选框样式

功能说明:基于JeecgBoot开源框架,JSwitch开关组件扩展,支持单个多选样式。效果展示:使用示例:{field: JSwitch,component: JSwitch,label: JSwitch,},{field: JSwitchCheckBox,component: JSwitch,label: JSwitchCheck…

(转)Kubernetes基础介绍

Kubernetes是用于自动部署、扩展和管理容器化应用程序的开源系统。

vue 播放海康m3u8视频流笔记

1、安装hls.jsnpm i hls 2、使用<el-dialogtitle"监控"top"5vh":visible.sync"dialogVisible"width"30%"><video id"video" style"width:100%;height:300px" controls><sourcetype"applicati…

如何清除 npm 缓存

清除 npm 缓存&#xff1a;利弊分析与操作指南 在使用 Node.js 和 npm 进行项目开发时&#xff0c;我们经常会与 npm install 命令打交道。这个过程中&#xff0c;npm 会在本地建立一个缓存机制&#xff0c;用以存储已下载的包&#xff0c;从而显著提升后续安装的速度。然而&am…