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类型,否则返回的字符串中会带有“\”

查询结果

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

(0)

相关推荐

  • Python模拟三级菜单效果

    本文实例为大家分享了Python模拟三级菜单效果的具体代码,供大家参考,具体内容如下 1.功能简介 此程序模拟多级菜单操作,实现按菜单项对应数字索引进入下级菜单,按b键回退到上一级菜单,按q键退出菜单.并用一个简化的学科专业目录进行了三级菜单测试,实际上此程序可适用任意多级菜单操作. 2.实现方法 本程序采用python语言编写,为了高效实现菜单操作,减少循环次数,关键定义了如下三个变量: current_menu_dict:非最低级菜单时为一个嵌套字典,在最低级菜单时为一个列表,存放当前级及后

  • python之wxPython菜单使用详解

    本文实例讲述了python中wxPython菜单的使用方法,分享给大家供大家参考.具体如下: 先来看看下面这段代码: import wx APP_EXIT=1 #定义一个控件ID class Example(wx.Frame): def __init__(self, parent, id, title): super(Example,self).__init__(parent, id, title) #调用你类的初始化 self.InitUI() #调用自身的函数 def InitUI(self

  • Python字典实现简单的三级菜单(实例讲解)

    如下所示: data = { "北京":{ "昌平":{"沙河":["oldboy","test"],"天通苑":["链接地产","我爱我家"]}, "朝阳":{"望京":["奔驰","陌陌"],"国贸":["CICC",&quo

  • python实现应用程序在右键菜单中添加打开方式功能

    最近项目组开发的一个小工具想要在右键菜单中添加打开方式,以有道云笔记为例进行了需求拆解和代码编写 1.需求拆解: 如何实现手动添加右键菜单的打开方式: Step1:打开注册表编辑器,Win+R->输入 "regedit" Step2:在HKEY_CLASSES_ROOT/*/shell (或者HKEY_LOCAL_MACHINE/SOFTWARE/Classes/*/shell ,两个目录是一样的) 添加一个key:YNote,然后在该项中新建项command,然后再编辑字符串,

  • python 创建弹出式菜单的实现代码

    python 创建弹出式菜单的实现代码            实现效果图: Python代码  import win32ui import win32api from win32con import * from pywin.mfc import window class MyWnd(window.Wnd): def __init__ (self): window.Wnd.__init__(self,win32ui.CreateWnd()) self._obj_.CreateWindowEx(W

  • 使用python实现省市三级菜单效果

    地区分三层结构例如: 大中华地区一级划分: 华东 华中 华北 西南 特别行政区 华南 ------------------------------------------------- 请输入你要查看的大中华地区名字:华中 ------------------包含的省名字二级:----------------- 湖北 湖南 河南 ------------------------------------------------- 请输入你要查看的省名字:湖北 --------------包含的城市

  • Python实现微信公众平台自定义菜单实例

    首先先获取access_token,并保存与全局之中 def token(requset): url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s' % ( Config.AppID, Config.AppSecret) result = urllib2.urlopen(url).read() Config.access_token = json.load

  • Python自动化开发学习之三级菜单制作

    本文实例为大家分享了Python三级菜单展示的具体代码,供大家参考,具体内容如下 作业需求: (1)运行程序输出第一级菜单 (2)选择一级菜单某项,输出二级菜单,同理输出三级菜单 (3)让用户选择是否要退出 (4)有返回上一级菜单的功能 data = { "天津":{ "南开区":{ "南开大学":{ "历史系":{}, "文学系":{}, "英语系":{}, }, "科技大学

  • 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) DE

  • python实现class对象转换成json/字典的方法

    本文实例讲述了python实现class对象转换成json字典的方法.分享给大家供大家参考,具体如下: # -*- encoding: UTF-8 -*- class Student: name = '' age = 0 def __init__(self, name, age): self.name = name self.age = age def convert_to_dict(obj): '''把Object对象转换成Dict对象''' dict = {} dict.update(obj

  • 把普通对象转换成json格式的对象的简单实例

    1.什么叫做JSON? JSON只是一种数据格式(它不是一种新的数据类型) var obj = {name: "中国", age: 5000};//->普通格式的对象 var jsonObj = {"name": "中国", "age": 5000};//->JSON格式的对象 (只要把普通对象的属性名用""(不能是'')包起来,这样的格式就是我们JSON格式的对象) var data = [

  • python将字符串转换成json的方法小结

    最近在工作中遇到了一个小问题,如果要将字符串型的数据转换成dict类型,我第一时间就想到了使用json函数.但是里面出现了一些问题 1.通过json来转换: In [1]: import json In [2]: mes = '{"InsId": 2, "name": "lege-happy", "CreationTime": "2019-04-23T03:18:02Z"}' In [3]: mes_to_

  • python将时分秒转换成秒的实例

    处理数据的时候遇到一个问题,从数据库里导出的数据是时分秒的格式:hh:mm:ss ,现在我需要把它转换成秒,方便计算. 原数据可能分两种情况,字段有可能是文本字符串类型的,也有可能是时间类型,他们的处理方法不一样,所以我们分开讨论. 1.字符串类型转换成秒 可以将其用 ':' 分隔开,分别得出时.分.秒,即可计算出秒数.所以我们定义如下函数: def str2sec(x): ''' 字符串时分秒转换成秒 ''' h, m, s = x.strip().split(':') #.split()函数

  • python 将dicom图片转换成jpg图片的实例

    主要原理:调整dicom的窗宽,使之各个像素点上的灰度值缩放至[0,255]范围内. 使用到的python库:SimpleITK 下面是一个将dicom(.dcm)图片转换成jpg图片的demo: import SimpleITK as sitk import numpy as np import cv2 def convert_from_dicom_to_jpg(img,low_window,high_window,save_path): lungwin = np.array([low_win

  • python 将视频 通过视频帧转换成时间实例

    我就废话不多说了,还是直接看代码吧! def frames_to_timecode(framerate,frames): """ 视频 通过视频帧转换成时间 :param framerate: 视频帧率 :param frames: 当前视频帧数 :return:时间(00:00:01:01) """ return '{0:02d}:{1:02d}:{2:02d}:{3:02d}'.format(int(frames / (3600 * fram

  • python函数中将变量名转换成字符串实例

    考虑到在日常中,常常需要对模型指标输出,但涉及多个模型的时候,需要对其有标示输出,故需要将模型变量名转换成字符串. 看到的基本方法有两种: 一.方法层面: 方法1(函数内推荐): def namestr(obj, namespace): return [name for name in namespace if namespace[name] is obj] print(namestr(lr_origin,globals()),'\n', namestr(lr_origin,globals())

  • java 读取excel文件转换成json格式的实例代码

    需要读取excel数据转换成json数据,写了个测试功能,转换正常: JSON转换:org.json.jar 测试类:  importFile.java: package com.siemens.util; import java.util.ArrayList; import java.util.List; import org.json.JSONException; import org.json.JSONObject; import org.apache.poi.ss.usermodel.R

  • Python实现将Excel转换成xml的方法示例

    本文实例讲述了Python实现将Excel转换成xml的方法.分享给大家供大家参考,具体如下: 最近写了个小工具 用于excel转成xml 直接贴代码吧: #coding=utf-8 import xlrd import datetime import time import sys import xml.dom.minidom import os print sys.getdefaultencoding() reload(sys) #就是这么坑爹,否则下面会报错 sys.setdefaulte

随机推荐