python list转换成树形结构_python递归查询菜单并转换成json实例

最近需要用python写一个菜单,折腾了两三天才搞定,现在记录在此,需要的朋友可以借鉴一下。

备注:文章引用非可执行完整代码,仅仅摘录了关键部分的代码

环境

数据库:mysql

python:3.6

表结构

CREATE TABLE `tb_menu` (

`id` varchar(32) NOT NULL COMMENT '唯一标识',

`menu_name` varchar(40) DEFAULT NULL COMMENT '菜单名称',

`menu_url` varchar(100) DEFAULT NULL COMMENT '菜单链接',

`type` varchar(1) DEFAULT NULL COMMENT '类型',

`parent` varchar(32) DEFAULT NULL COMMENT '父级目录id',

`del_flag` varchar(1) NOT NULL DEFAULT '0' COMMENT '删除标志 0:不删除 1:已删除',

`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

PRIMARY KEY (`id`) USING BTREE

) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='菜单表';

Python代码

Menu对象中,有一个子菜单列表的引用“subMenus”,类型为list

核心代码

def set_subMenus(id, menus):

"""

根据传递过来的父菜单id,递归设置各层次父菜单的子菜单列表

:param id: 父级id

:param menus: 子菜单列表

:return: 如果这个菜单没有子菜单,返回None;如果有子菜单,返回子菜单列表

"""

# 记录子菜单列表

subMenus = []

# 遍历子菜单

for m in menus:

if m.parent == id:

subMenus.append(m)

# 把子菜单的子菜单再循环一遍

for sub in subMenus:

menus2 = queryByParent(sub.id)

# 还有子菜单

if len(menus):

sub.subMenus = set_subMenus(sub.id, menus2)

# 子菜单列表不为空

if len(subMenus):

return subMenus

else: # 没有子菜单了

return None

测试方法

def test_set_subMenus(self):

# 一级菜单

rootMenus = queryByParent('')

for menu in rootMenus:

subMenus = queryByParent(menu.id)

menu.subMenus = set_subMenus(menu.id, subMenus)

备注:基本流程是:先查询一级菜单,然后分别把该级菜单的id、和这级菜单的子菜单列表传入set_subMenus方法,递归进行子菜单列表的下级菜单设置;

支持传递菜单Id,查询该菜单下面的所有子菜单。传递空字符,则从根目录开始查询

在“rootMenus ”对象中,可以看到完整的菜单树形结构

转Json

我采用的ORM框架是:sqlalchemy,直接从数据库中查询出来的Menu对象,转Json时会报错。需要重新定义一个DTO类,来把Menu对象转成Dto对象。

MenuDto

class MenuDto():

def __init__(self, id, menu_name, menu_url, type, parent, subMenus):

super().__init__()

self.id = id

self.menu_name = menu_name

self.menu_url = menu_url

self.type = type

self.parent = parent

self.subMenus = subMenus

def __str__(self):

return '%s(id=%s,menu_name=%s,menu_url=%s,type=%s,parent=%s)' % (

self.__class__.__name__, self.id, self.menu_name, self.menu_url, self.type, self.parent)

__repr = __str__

于是,重新定义了递归设置子菜单的方法

def set_subMenuDtos(id, menuDtos):

"""

根据传递过来的父菜单id,递归设置各层次父菜单的子菜单列表

:param id: 父级id

:param menuDtos: 子菜单列表

:return: 如果这个菜单没有子菜单,返回None;如果有子菜单,返回子菜单列表

"""

# 记录子菜单列表

subMenuDtos = []

# 遍历子菜单

for m in menuDtos:

m.name = to_pinyin(m.menu_name)

if m.parent == id:

subMenuDtos.append(m)

# 把子菜单的子菜单再循环一遍

for sub in subMenuDtos:

menus2 = queryByParent(sub.id)

menusDto2 = model_list_2_dto_list(menus2,

"MenuDto(id='', menu_name='', menu_url='', type='', parent='', subMenus='')")

# 还有子菜单

if len(menuDtos):

if len(menusDto2):

sub.subMenus = set_subMenuDtos(sub.id, menusDto2)

else: # 没有子菜单,删除该节点

sub.__delattr__('subMenus')

# 子菜单列表不为空

if len(subMenuDtos):

return subMenuDtos

else: # 没有子菜单了

return None

备注:

当一个菜单没有子菜单时,删除掉“subMenus”属性,否则转Json时会出现空值

model_list_2_dto_list 方法可以把Menu列表转成MenuDto列表

to_pinyin 是把汉字转成拼音的方法,在这里不用关注

View层返回Json的方法

def get(self):

param = request.args

id = param['id']

# 如果id为空,查询的是从根目录开始的各级菜单

rootMenus = queryByParent(id)

rootMenuDtos = model_list_2_dto_list(rootMenus,

"MenuDto(id='', menu_name='', menu_url='', type='', parent='', subMenus='')")

# 设置各级子菜单

for menu in rootMenuDtos:

menu.name = to_pinyin(menu.menu_name)

subMenus = queryByParent(menu.id)

if len(subMenus):

subMenuDtos = model_list_2_dto_list(subMenus,

"MenuDto(id='', menu_name='', menu_url='', type='', parent='', subMenus='')")

menu.subMenus = set_subMenuDtos(menu.id, subMenuDtos)

else:

menu.__delattr__('subMenus')

menus_json = json.dumps(rootMenuDtos, default=lambda o: o.__dict__, sort_keys=True, allow_nan=false,

skipkeys=true)

# 需要转字典,否则返回的字符串会带有“\”

menus_dict = json_dict(menus_json)

return fullResponse(menus_dict)

fullResponse

from flask import jsonify

def fullResponse(data='', msg='', code=0):

if msg == '':

return jsonify({'code': code, 'data': data})

elif data == '':

return jsonify({'code': code, 'msg': msg})

else:

return jsonify({'code': code, 'msg': msg, 'data': data})

备注:python中json和字典的含义类似,在最后json返回给页面时,需要先使用json_dict方法转成dict类型,否则返回的字符串中会带有“\”

查询结果

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

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

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

相关文章

oracle轮询方式循环输出,LGWR的两种模式(POST/WAIT和POLLING)

11.2之前,oracle的lgwr写入模式为post/wait11.2之后新增了polling模式,可以与post/wait模式自动切换通过隐藏参数 _use_adaptive_log_file_sync 参数来控制查看该隐藏参数的方法:SELECT x.ksppinm NAME, y.ksppstvl VALUE, x.ksppdesc descr…

ios上架图片在线制作_不同风格gif在线制作,公众号动态图片制作方法

现在运营公众号的主要方式就通过文章来进行宣传推广,在公众号文章中使用GIF动态图是非常常见的一种图片展现的方式,让文章整体效果看起来更加的生动有趣,所以很多的运营者在日常的工作和生活中会手机许多的动图素材,方便以后的使用…

python3.8学习_python3.8.1 入门基础学习 之 【字典】 学习

python3.8.1 入门基础学习 之 【字典】 学习字典是另一种可变容器模型,且可存储任意类型对象。字典的每个键值(key>value)对用冒号(:)分割,每个对之间用逗号(,)分割,整个字典包括在花括号({})中 ,格式如下所示:1、python3.8.1 …

oracle 树查询语句,oracle 树查询 语句

格式:SELECT columnFROM table_nameSTART WITH columnvalueCONNECT BY PRIOR 父主键子外键select lpad( ,4*(level-1))||name name,job,id,super from empstart with super is nullconnect by prior idsuper例子:原始数据:select no,q from a…

table tr省略后鼠标移入显示相应信息_中考来了,人机对话、信息技术考试要求看过来...

半岛记者 魏海洋今年的中考将拉开大幕,九年级英语听说人机对话考试(以下简称“人机对话考试”)将于4月20日(周六)至21日(周日)进。八年级信息技术考试将于4月22日(周一)进行,市招考办提醒广大考生,按照准考证规定时间及时参加考试。关于两门考…

大数据平台容量评估_大数据平台

系统概述大数据应用支撑平台提供数据支撑服务,对外发布数据服务进行数据价值变现。包含数据采集、数据治理、数据交换、数据存储、数据计算相关组件的搭建、验证,并建立大数据仓库。b)功能要求1.数据采集,大数据平台数据源层有各类型数据源&a…

oracle数据库访问sqlserver2008,透过SQL Server 2008访问Oracle 10g的配置方法

之前写过一篇关于SQL Server 访问MySQL数据库的文章,最近正好又遇到需要访问Oracle 的情况,将配置过程记录下来也供大家参考。准备工作事先在需要访问Oracle 数据库的主机上完成以下工作:1. 安装SQL Server 数据库:SQL Server 200…

局域网限速软件_2号破解app重器推荐一款强大的快捷软件

破解版精破解版精品软件一些软件需要使用者付费购买才能使用其所有功能(或者才能解除使用期限),这时一些计算机高手就破解这个软件,使其不用付费也可以完全使用全部功能(或者永久使用),这种软件就叫破解版软件。此公众号中的破解版软件都源于…

人工智能到底是啥_人工智能 (AI) 是什么?| Oracle 中国

人工智能是什么?简单来说,人工智能 (AI) 是指可模仿人类智能来执行任务,并基于收集的信息对自身进行迭代式改进的系统和机器。AI 具有多种形式。例如:聊天机器人使用 AI 更快速高效地理解客户问题并提供更有效的回答智能助手使用 …

平板电脑办公软件_大屏平板互动软件-平板电脑触摸大屏控制软件

随着数字化时代的到来,触摸大屏软件的应用范围,更加宽广,无论走到哪里都能够见到,各式各样的触摸屏一体机、LED液晶屏,拼接屏等多种展示器,在这些设备上面,均能够安装着各种功能不同软件&#x…

oracle 备份教研归档失败,归档日志丢失造成Rman备份失败解决办法

--测试库的归档日志文件被无意删除了,下面是解决步骤RMAN> backup as compressed backupset database plus archivelog delete input;启动 backup 于 24-2月 -12当前日志已存档使用通道 ORA_DISK_1使用通道 ORA_DISK_2MAN-00571: RMAN-00569: ERROR MESSAGE STA…

python两个二维数组加法_对二维数组的多个列进行Numpy平均

首先,在我看来,你根本没有平均列的平均值,你只是一次平均两个数据点。在我看来,你最好不要使用reshaping数组,这样你就有了一个可以直接提供给mean的Nx2数据结构。如果列数不太兼容,可能必须先填充它。然后…

苹果6屏幕多大_苹果12使用高通X55,10亿买下的英特尔基带何时能派上用场

阅读本文前,请您先点击上面的蓝色字体,再点击“关注”,这样您就可以免费收到最新内容了。每天都有分享,完全是免费订阅,请放心关注。声明:本文转载自网络,如有侵权,请在后台留言联系…

ora29280 oracle,细节:utl_file_dir错误设置导致ORA-29280

sysORADG(192.168.190.241)> show parameter utlNAME TYPE VALUE------------------------------------ ---------------------- ------------------------------utl_file_dir string /oracle/test123, /oracle/logmnr <-修改前的值sysORADG(192.168.190.241)> alter …

global在python_在Python中使用“global”关键字

在Python中使用“global”关键字我从阅读文档中了解到&#xff0c;Python有一个单独的函数命名空间&#xff0c;如果我想在该函数中使用全局变量&#xff0c;我需要使用global。我正在使用Python 2.7&#xff0c;我尝试了这个小测试>>> sub [0, 0, 0, 0]>>>…

odd raio值 是什麼_乳化油相所需的HLB值

前面有分享过《常用乳化剂HLB值一览表》&#xff0c;为了方便大家查阅HLB值&#xff0c;《有机概念图、HLB值与乳化剂筛选》一文中介绍了HLB值的计算方法以及乳化剂的筛选。今天分享乳化油所需要HLB,方便大家查阅&#xff0c;油相在O/W乳状液和W/O乳状液中所需的HLB值是不同的&…

oracle12c创建schema,Oracle 12c Schema Demo 安装

Oracle 12cR2 schema demo的安装主要参考README.md文件以及Dave的文章&#xff1a;http://www.cndba.cn/dave/article/1985但其中遇到了其他问题(CDB问题)&#xff0c;以下记录安装过程以及故障处理。https://www.cndba.cn/9527/article/2303把文件拷贝到$ORACLE_HOME/demo目录…

4k纸是几厘米乘几厘米_4K纸有多大 。。厘米

展开全部4K纸通常长&#xff1a;53cm&#xff0c;宽&#xff1a;38cm。4K纸一般指“四开”大小62616964757a686964616fe4b893e5b19e31333431343039的纸张&#xff0c;目前有“国际大度”和“国际正度”的两种标准。国际大度四开纸的长宽为&#xff1a;5843cm&#xff1b;国际大…

搜狗输入法在idea打不了汉字_IDEA开发软件在linux环境下使用搜狗输入法无法进行中文输入...

IDEA开发软件在linux环境下使用搜狗输入法无法进行中文输入找到bin目录下的idea.sh文件(其他编辑器也是一样如pycharm.sh、clion.sh)。使用文本编译器打开&#xff0c;找到# -----------------# Run the IDE.# -----------------在前面添加export GTK_IM_MODULEfcitxexport QT_…

caj文件浏览器_caj文件怎么转换成pdf文件?试试这样操作,3步成功转换

诸位小伙伴用过caj文件吗&#xff1f;和pdf文件类似&#xff0c;也和电子书格式有点像&#xff0c;是我们办公中会用到的格式文件&#xff0c;不过假如你分享了一份caj格式的文档给别人&#xff0c;如果他们的电脑上没有安装对应的浏览器&#xff0c;则无法打开、阅读文件哦。鉴…