惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
aimingoo的专栏
aimingoo的专栏
爱范儿
爱范儿
D
Docker
I
InfoQ
Microsoft Security Blog
Microsoft Security Blog
G
Google Developers Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Vercel News
Vercel News
H
Hackread – Cybersecurity News, Data Breaches, AI and More
T
Tailwind CSS Blog
D
DataBreaches.Net
月光博客
月光博客
N
Netflix TechBlog - Medium
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
V
Visual Studio Blog
MyScale Blog
MyScale Blog
B
Blog
阮一峰的网络日志
阮一峰的网络日志
L
LangChain Blog
Recent Announcements
Recent Announcements
Microsoft Azure Blog
Microsoft Azure Blog
WordPress大学
WordPress大学

博客园 - oO_Ray

conda pack环境迁移后jupyterlab kernel python环境找不到解决办法 启动carla-simulator时遇到 libomp.so.5 文件找不到的问题 已知圆心坐标和圆半径,求圆边点坐标 使用Python语言 推荐一款好用的json导出execl格式的文件的js工具-JsonExportExcel Locust 性能测试工具安装使用说明 pip使用的基本命令 python制作 whl 源文件,并制作本地pip源 Appium Android sdk自动化工具安装 roboframework-ride运行案例时报 Error 267 错误问题 Flask 编写http接口api及接口自动化测试 ssh免密码登录快速配置方法 Ansible 介绍和使用 Python开发规范 121、Django rest framework入门使用 60、Docker 学习笔记(CentOS 7.1) 37、解决 HTMLTestRunner 中文显示乱码的问题 13、Selenium+python+API分类总结 35、XPath的使用示例 使用CSS选择器进行元素定位
Python 递归返回树形菜单JSON串 <flask>
oO_Ray · 2018-02-08 · via 博客园 - oO_Ray

需求:菜单管理功能(增、删、改),多级树形菜单展示

数据库表设计

create table if not exists Menu(
    id serial  primary key ,
    title varchar (50) not null ,
    parent_id int ,
    url varchar (100),
    app_id int ,
    icon varchar (50),
    sortby int default 0,
    create_time timestamp,
    update_time timestamp,
    foreign key (parent_id) references Menu(id) on delete cascade on update cascade
);

Model 定义

class Menu:
    def __init__(self, id, title, parent_id, url, app_id, icon, sort_by, create_time, update_time, subMenus):
        self._id = id
        self._title = title
        self._parent_id = parent_id
        self._url = url
        self._app_id = app_id
        self._icon = icon
        self._sortby = sort_by
        self._create_time = create_time
        self._update_time = update_time
        self._subMenus = subMenus

    @property
    def id(self):
        return self._id
    @property
    def title(self):
        return self._title
    @property
    def parent_id(self):
        return self._parent_id
    @property
    def url(self):
        return self._url
    @property
    def app_id(self):
        return self._app_id
    @property
    def icon(self):
        return self._icon
    @property
    def sortby(self):
        return self._sortby
    @property
    def subMenus(self):
        return self._subMenus

理论上Models应该中的参数应该和数据库表字段对应,但是subMenus我们不需要存库,反给前端用的。

核心代码

def set_subMenus(id, menus):
        """
        :param id: 父id
        :param subMenu:子菜单列表
        :return: 没有子菜单返回None 有子菜单返回子菜单列表
        """
        try:
            _subMenus = []

            for menu in menus:
                if menu.parent_id == id:
                    _subMenus.append(menu)
            for sub in _subMenus:
                menu2 = _query_sub_menu_info(sub.id)
                if len(menus):
                    sub._subMenus = set_subMenus(sub.id, menu2)
                else:
                    sub.__delattr__('_subMenus')
            # 子菜单列表不为空
            if len(_subMenus):
                # print(sub_list)
                return _subMenus
            else:  # 没有子菜单了
                return None
        except Exception as e:
            LOG.exception('error query_sub_menu_info !')
            raise e
_query_sub_menu_info 方法是查询返回

测试方法:

def test_sub_menu_list(self):
        Menus = []
        rootMenu = GuardianModelDao._query_root_menu_info()
        for root in rootMenu:
            subMenu = GuardianModelDao._query_sub_menu_info(root.id)
            root = jsonpickle.loads(jsonpickle.encode(root))
            if root.subMenus is not None:
                root.subMenus.append(GuardianModelDao.set_subMenus(root.id, subMenu))
                Menus.append(root)