• 权限组件(3):默认选中非菜单(二级菜单)


    我们要的效果是点中添加、编辑、删除缴费记录,左边的账单列表会被默认选中

    一、在权限表里新建一个自关联的字段pid 

    rbac/models.py

    class Permission(models.Model):
        """
        权限表
        """
        title = models.CharField(verbose_name='标题', max_length=32)
        url = models.CharField(verbose_name='含正则的URL', max_length=128)
    
        menu = models.ForeignKey(verbose_name='所属菜单', to=Menu, null=True, blank=True,
                                 help_text='null表示不是菜单,非null表示是二级菜单', on_delete=models.CASCADE
                                 )
    
        pid = models.ForeignKey(verbose_name='关联的权限', to='Permission', null=True, blank=True, related_name='parents',
                                help_text='对于非菜单权限需要选择一个可以成为菜单的权限,用于做默认展开和选中菜单',
                                on_delete=models.CASCADE
                                )
    
        def __str__(self):
            return self.title

    说明:拿客户列表来举例:

    idtitleurlmenu_idpid
    1 客户列表 /customer/list/ 1 null
    2 增加客户 /customer/add/ null 1
    3 编辑客户 /customer/edit/(?Pd+)/ null 1
    4 删除客户 /customer/del/(?Pd+)/ null 1

    没有pid,有menu_id的是二级菜单,有pid,没有menu_id的是具体的权限,是不可以做菜单的。我们的目的是让用户点击增加、编辑、删除客户的时候,客户列表被默认选中

     

    二、初始化权限中增加权限id的其父id(也就是pid、二级菜单)

    rbac/service/init_permission.py

    from permission_learn import settings
    
    
    def init_permission(current_user, request):
        """
        用户权限的初始化
        :param current_user:  当前登录用户
        :param request:
        :return:
        """
    
        permission_menu_queryset = current_user.roles.filter(permissions__isnull=False).values(
            'permissions__id',  
            'permissions__title',
            'permissions__url',
            'permissions__pid_id',  # +
            'permissions__menu_id',
            'permissions__menu__title',
            'permissions__menu__icon',
        )
    
        menu_dict = {}
        permission_list = []
    
        for item in permission_menu_queryset:
            permission_list.append(
                {'id': item['permissions__id'], 'url': item['permissions__url'], 'pid': item['permissions__pid_id']}
            )
    
            menu_id = item['permissions__menu_id']
    
            if not menu_id:
                continue
    
            # 二级菜单没有pid
            second_menu = {'id':item['permissions__id'],'title': item['permissions__title'], 'url': item['permissions__url']}
    
            if menu_id in menu_dict:
                menu_dict[menu_id]['second_menu'].append(second_menu)
            else:
                menu_dict[menu_id] = {
                    'title': item['permissions__menu__title'],
                    'icon': item['permissions__menu__icon'],
                    'second_menu': [second_menu, ]
                }
    
        request.session[settings.PERMISSION_SESSION_KEY] = permission_list
        request.session[settings.MENU_SESSION_KEY] = menu_dict

    初始化权限的时候,给具体权限增加了id和它的pid,给二级菜单增加了id,是为了当用户点击具体权限的时候,可以拿到这个权限的pid,然后和二级菜单的id做比较,如果一样就给二级菜单的id加上选中的样式。

     

    三、中间件获取到当前点击的权限的二级菜单的id

    rbac/middlewares/rbac.py 

    import re
    
    from django.utils.deprecation import MiddlewareMixin
    from django.shortcuts import HttpResponse
    from permission_learn import settings
    
    
    class RbacMiddleware(MiddlewareMixin):
        def process_request(self, request):
            white_list = settings.WHITE_LIST
            current_path = request.path_info
    
            for valid_url in white_list:
                if re.match(valid_url, current_path):
                    return None
    
            permission_list = request.session.get(settings.PERMISSION_SESSION_KEY)
    
            if not permission_list:
                return HttpResponse('请先登录')
    
            has_permission = False
    
            for item in permission_list:
                reg = '^%s$' % item['url']
                if re.match(reg, current_path):
                    has_permission = True
    
                    # 如果是二级菜单(/customer/list/),没有pid,采用id,就是二级菜单的id,如果是具体权限(/customer/add/),就会采用pid,也是二级菜单的id
                    request.current_selected_permission = item['pid'] or item['id']  # 前面为True就用前面的,前面为False就用后面的
                    break
    
            if not has_permission:
                return HttpResponse('未获取权限,请先获取权限')

     

    四、在templatestag给用户选中的权限的二级菜单加样式

    rbac/templatestag/rbac.py

    import re
    from
    collections import OrderedDict from django.conf import settings from django.template import Library register = Library() @register.inclusion_tag('rbac/multi_menu.html') def multi_menu(request): menu_dict = request.session[settings.MENU_SESSION_KEY]

    key_list = sorted(menu_dict) ordered_dict = OrderedDict() for key in key_list: menu = menu_dict[key] menu['class'] = 'hide' for second_menu in menu['second_menu']: # second_menu['id']是二级菜单的id,current_selected_permission是当前所选权限的二级菜单的id if second_menu['id'] == request.current_selected_permission: second_menu['class'] = 'active' menu['class'] = '' ordered_dict[key] = menu context = { 'menus': ordered_dict, } return context
  • 相关阅读:
    js append()和appendChild()和insertBefore()的区别
    webpack打包工具简单案例
    Vue $ref 的用法
    Vue学习笔记-作用域插槽
    Vue学习笔记-插槽基本使用
    Vue学习笔记-父子通信案例
    Echarts案例-折线图
    Echarts案例-柱状图
    软件构造实验三-递归下降分析分析法
    软件构造实验二-拷贝一个c文件 将其中的关键字int替换成float
  • 原文地址:https://www.cnblogs.com/lshedward/p/10496624.html
Copyright © 2020-2023  润新知