全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

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

备注:

  1. 当一个菜单没有子菜单时,删除掉“subMenus”属性,否则转Json时会出现空值
  2. model_list_2_dto_list 方法可以把Menu列表转成MenuDto列表
  3. 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类型,否则返回的字符串中会带有“\”

查询结果

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


# 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小时内与您取得联系。