【Python】 多层级嵌套循环

发布时间 2023-11-23 17:43:26作者: 是阿杰呀

1. 渲染多级菜单, 并调整数据

# 生成 菜单树状目录
class MenuTreeView(APIView):
    # 多层级 生成树状目录
    def generate_menu_tree(self, parent_menu):
        temp_menu_list = []
        sub_menus = models.Menu.objects.filter(parent=parent_menu)
        for sub_menu in sub_menus:
            _temp = {'id': sub_menu.id, 'label': sub_menu.title, 'sortNo': sub_menu.sortNo, 'url': sub_menu.url,
                     'show': 0, 'children': self.generate_menu_tree(sub_menu)}
            temp_menu_list.append(_temp)
        return temp_menu_list

    # 多层级 修改 show值
    def process_nested(self, data, menu_id_list):
        if isinstance(data, dict):  # 如果是字典
            if data['id'] in menu_id_list:
                data['show'] = 1
            if isinstance(data['children'], (dict, list)):  # 如果值是字典或列表,递归调用process_nested
                self.process_nested(data['children'], menu_id_list)
        elif isinstance(data, list):  # 如果是列表
            for item in data:
                if isinstance(item, (dict, list)):  # 如果元素是字典或列表,递归调用process_nested
                    self.process_nested(item, menu_id_list)

    # 多层级遍历 子节点中show值, 来修改父节点的show值
    def update_show(self, data):
        for item in data:
            children = item.get('children')
            if children:
                # 递归处理子节点
                self.update_show(children)
                # 判断子节点中是否存在show=1的情况
                has_show_1 = any(child.get('show') == 1 for child in children)
                if has_show_1:
                    item['show'] = 1
        return data

    def get(self, request):
        print(request.GET)
        res = []
        try:
            req_data = request.GET.dict()
            flag = req_data.get('flag')  # 获取操作方式, flag==all, 获取所有菜单, or 获取当前用户的菜单
            # 生成 所有菜单树目录
            menu_tree = self.generate_menu_tree(None)
            if flag == 'all':
                _menu_id_list = models.Menu.objects.all().values_list('id', flat=True)
                self.process_nested(menu_tree, _menu_id_list)  # 更新 show=1
            else:
                # 获取当前用户的菜单id
                _menu_id_list = []
                for i in request.user.roles.all():
                    _menu_id_list.extend(i.menu.all().values_list('id', flat=True))
                _menu_id_list = set(_menu_id_list)
                self.process_nested(menu_tree, _menu_id_list)  # 更新 show=1
                self.update_show(menu_tree)  # 更新 父级菜单 show=1
            res = menu_tree
        except:
            traceback.print_exc()
            return JsonError(msg='错误')
        return JsonResponse(res)