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

备注:文章引用非可执行完整代码,仅仅摘录了关键部分的代码
环境
表结构
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
备注:
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类型,否则返回的字符串中会带有“\”
查询结果
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# python递归菜单
# python
# 转换json
# 递归解析json
# python3 json数据格式的转换(dumps/loads的使用、dict to str/str
# Python中xml和json格式相互转换操作示例
# Python基于pandas实现json格式转换成dataframe的方法
# python 对象和json互相转换方法
# 利用python将json数据转换为csv格式的方法
# Python实现将Excel转换为json的方法示例
# Python 提取dict转换为xml/json/table并输出的实现代码
# python实现class对象转换成json/字典的方法
# Python实现把json格式转换成文本或sql文件
# python对象与json相互转换的方法
# 递归
# 转成
# 为空
# 遍历
# 一遍
# 象中
# 有一
# 在这里
# 更新时间
# 再循环
# 在此
# 是从
# 可以看到
# 报错
# 数据库中
# 查询结果
# 需要用
# 可执行
# 中会
# 大家多多
相关文章:
如何获取PHP WAP自助建站系统源码?
免费制作统计图的网站有哪些,如何看待现如今年轻人买房难的情况?
网站制作需要会哪些技术,建立一个网站要花费多少?
网站制作软件有哪些,制图软件有哪些?
如何高效完成自助建站业务培训?
如何在景安云服务器上绑定域名并配置虚拟主机?
建站之星安装需要哪些步骤及注意事项?
如何登录建站主机?访问步骤全解析
建站之星如何一键生成手机站?
建站之星后台密码遗忘?如何快速找回?
建站VPS能否同时实现高效与安全翻墙?
教育培训网站制作流程,请问edu教育网站的域名怎么申请?
php8.4新语法match怎么用_php8.4match表达式替代switch【方法】
实例解析Array和String方法
手机怎么制作网站教程步骤,手机怎么做自己的网页链接?
建站之星CMS建站配置指南:模板选择与SEO优化技巧
如何通过虚拟主机快速搭建个人网站?
建站VPS配置与SEO优化指南:关键词排名提升策略
非常酷的网站设计制作软件,酷培ai教育官方网站?
如何在Mac上搭建Golang开发环境_使用Homebrew安装和管理Go版本
网站制作外包价格怎么算,招聘网站上写的“外包”是什么意思?
盐城做公司网站,江苏电子版退休证办理流程?
如何高效利用亚马逊云主机搭建企业网站?
如何选择可靠的免备案建站服务器?
高防服务器如何保障网站安全无虞?
网站视频制作书签怎么做,ie浏览器怎么将网站固定在书签工具栏?
红河网站制作公司,红河事业单位身份证如何上传?
Thinkphp 中 distinct 的用法解析
建站之星代理如何获取技术支持?
5种Android数据存储方式汇总
如何制作新型网站程序文件,新型止水鱼鳞网要拆除吗?
制作网站的公司有哪些,做一个公司网站要多少钱?
如何选择最佳自助建站系统?快速指南解析优劣
建站VPS选购需注意哪些关键参数?
如何在宝塔面板中创建新站点?
枣阳网站制作,阳新火车站打的到仙岛湖多少钱?
建站主机是否属于云主机类型?
如何用狗爹虚拟主机快速搭建网站?
网站企业制作流程,用什么语言做企业网站比较好?
怀化网站制作公司,怀化新生儿上户网上办理流程?
h5在线制作网站电脑版下载,h5网页制作软件?
制作网站怎么制作,*游戏网站怎么搭建?
制作无缝贴图网站有哪些,3dmax无缝贴图怎么调?
唐山网站制作公司有哪些,唐山找工作哪个网站最靠谱?
如何高效配置IIS服务器搭建网站?
建站主机功能解析:服务器选择与快速搭建指南
江苏网站制作公司有哪些,江苏书法考级官方网站?
制作网站的基本流程,设计网站的软件是什么?
如何使用Golang table-driven基准测试_多组数据测量函数效率
微网站制作教程,我微信里的网站怎么才能复制到浏览器里?
*请认真填写需求信息,我们会在24小时内与您取得联系。