zoukankan      html  css  js  c++  java
  • Django--CRM--菜单排序等

    一 . 菜单排序

      1.我们想把菜单排序.首先给菜单加上权重,权重大的排在上面, 这就要在菜单表上加上一个权重字段.

      

      2. 我们在菜单表里面把权重改一下

      

      3. 需要把权重字段的信息拿出来放到session中去

      4. 在自定义过滤器里面进行排序  然后其他的不用改就会显示成排序后的菜单

    from django import template
    from django.conf import settings
    from collections import OrderedDict
    
    register = template.Library()
    
    @register.inclusion_tag('menu.html')
    def my_menu(request):
        url = request.path
        # 二级菜单
        menu_dict = request.session[settings.MENU_SESSION_KEY]  # 不能在这循环,需要模板里面循环
        # 按照添加的顺序进行展示 有序字典
        ordered_dict = OrderedDict()
        # ret是按照权重排完序的key
        ret = sorted(menu_dict, key=lambda x: menu_dict[x]['weight'], reverse=True)
        for i in ret:
            ordered_dict[i] = menu_dict[i]
        return {'menu_list': ordered_dict.values()}

    二 . 二级菜单选中并且展开

      

    # 实现思路
    1. 当我们点击二级菜单的时候, 让他显示被选中的状态,需要class="active"
    2. 进入菜单页面的时候,除了输入的二级菜单对应的一级菜单外,其他的一级菜单都应该收起来
    3. 当我们点击另一个一级菜单的时候, 其他的一级菜单全部都收起来

      

      

       

      来看一下效果

         

    三. 非菜单权限的归属

      上面的操作有点瑕疵:

       

      造成上面的原因是添加和编辑等和二级菜单没啥关系,影响不了二级菜单的展开与隐藏, 解决这个问题,需要把他们添加一对多的关系

      

      看一下权限表

      

      

    1 . 由上图可知, 如果点击的是编辑增加等标签,他的parent_id就是二级菜单的id, 这样我们就可以通过点击添加或者编辑找到二级标签的id,
        那么我们就可以在自定义过滤器中判断,如果拿到的是二级id,那么就让这个菜单添加被选中并且展开的状态
    2 . 我们需要把parent_id 和 二级菜单的id放到session中去

      

      然后我们需要在权限验证的中间件中拿到二级菜单的id

     1 from django.utils.deprecation import MiddlewareMixin
     2 from django.shortcuts import HttpResponse, redirect
     3 from django.conf import settings
     4 import re
     5 
     6 class RbacMiddleWare(MiddlewareMixin):
     7     def process_request(self, request):
     8         # 获取当前访问的页面
     9         url = request.path
    10         # print('>>>>>', url)
    11         # 为了让index页面正常不报错
    12         request.current_menu_id = None
    13         # 在中间件中那 用反射
    14         # setattr(request, settings.CURRENT_MENU_ID, None)
    15 
    16         # 白名单
    17         for i in settings.WHITE_LIST:
    18             # match 匹配上得到一个对象,匹配不上返回None
    19             if re.match(i, url):
    20                 return
    21         # 获取登录状态
    22         is_login = request.session['is_login']
    23         # 没有登录跳转登录页面
    24         if not is_login:
    25             return redirect('login')
    26 
    27         # 免认证
    28         for i in settings.NO_PERMISSION_LIST:
    29             # match 匹配上得到一个对象,匹配不上返回None
    30             if re.match(i, url):
    31                 return
    32 
    33         # 获取当前用户的权限, 要用get去拿,没有显示None,[]就会报错
    34         permission_list = request.session.get(settings.PERMISSION_SESSION_KEY)
    35         # print(permission_list)
    36         # 权限的校验
    37         for permission in permission_list:
    38             # print('>>>>',permission)
    39             if re.match(f'^{permission.get("url")}$', url):
    40 
    41                 pid = permission.get('pid')
    42                 id = permission.get('id')
    43                 if pid:
    44                     # 当前访问的是添加编辑的功能
    45                     request.current_menu_id = pid   # 用request才能传过去
    46                     # 用反射
    47                     # setattr(request, settings.CURRENT_MENU_ID, pid)
    48                 else:
    49                     # 访问的是二级菜单
    50                     request.current_menu_id = id
    51                     # 用反射
    52                     # setattr(request, settings.CURRENT_MENU_ID, id)
    53                 return
    54         # 没有匹配成功
    55         return HttpResponse('你的level不够!!')
    权限验证中获取二级菜单的id

     

      当然,可以以配置到settings中去, 操作方法在上面写了,注释的那个就是

      

     四 . 路径导航

      

      

    from django.utils.deprecation import MiddlewareMixin
    from django.shortcuts import HttpResponse, redirect
    from django.conf import settings
    import re
    
    class RbacMiddleWare(MiddlewareMixin):
        def process_request(self, request):
            # 获取当前访问的页面
            url = request.path
            # 当前访问的路径id
            request.current_menu_id = None
    
            # 路径导航(面包线导航)的列表
            request.breadcrumb_list = [{'title': '首页', 'url': '/index/'}]
    
            # 白名单
            for i in settings.WHITE_LIST:
                # match 匹配上得到一个对象,匹配不上返回None
                if re.match(i, url):
                    return
            # 获取登录状态
            is_login = request.session['is_login']
            # 没有登录跳转登录页面
            if not is_login:
                return redirect('login')
    
            # 免认证
            for i in settings.NO_PERMISSION_LIST:
                # match 匹配上得到一个对象,匹配不上返回None
                if re.match(i, url):
                    return
    
            # 获取当前用户的权限, 要用get去拿,没有显示None,[]就会报错
            permission_dict = request.session.get(settings.PERMISSION_SESSION_KEY)
    
            # 权限的校验
            for permission in permission_dict.values():
    
                if re.match(f'^{permission.get("url")}$', url):
    
                    pid = permission.get('pid')
                    id = permission.get('id')
                    if pid:
                        # 当前访问的是添加编辑的功能
                        request.current_menu_id = pid   # 用request才能传过去
              
                        # 当点击添加或者编辑的时候就走的这里
                        parent = permission_dict[str(pid)]
                        request.breadcrumb_list.append({'url': parent['url'], 'title': parent['title']})
    
                    else:
                        # 访问的是二级菜单
                        request.current_menu_id = id
    
                        # 如果没有pid就证明是二级菜单
                    request.breadcrumb_list.append({'url': permission['url'], 'title': permission['title']})
                    return
            # 没有匹配成功
            return HttpResponse('你的level不够!!')
    权限验证中间件中的路径导航

      

      

     五 . 权限粒度控制按钮级别

        权限粒度控制按钮级别意思就是你有这个权限给你展示这个按钮,你没有这个权限就不给你展示

        思路:

          1. 把用户的所有权限放到一个列表里面

          2. 如果前端展示的按钮在用户的权限列表了,那么就显示

          3. 由于url的别名不会总该,所以这里我们用别名来表示权限的url

          4. 用url的别名, 要把别名写到数据库

          5. 在权限表里面加一个别名字段,并且这个name要是唯一的, 要注意的是, 这个字段是后添加的, 需要先设置default, 但是不能直接填unique=True

          6. 迁移完之后,把别名一一对应手动填写到权限表的name字段

            

          7. 再到name字段中添加unique=True, 然后在进行数据库迁移

          

          8. 我们需要获得数据库中的name字段的数据,这样我们可以把permission_dict[i['permissions__id']] 改为 permission_dict[i['permissions__name']] 因为都是唯一的

              由于key 从id 改为 name了,所以我们的路径导航里面的用到的permissions__id也要做出相应的改变,之前用的是二级菜单的id, 由于存在关系,所以可以通过pid找到

                二级菜单的name,然后中间件中的引用的str(pid)也要改成name

      

     1 from django.utils.deprecation import MiddlewareMixin
     2 from django.shortcuts import HttpResponse, redirect
     3 from django.conf import settings
     4 import re
     5 
     6 class RbacMiddleWare(MiddlewareMixin):
     7     def process_request(self, request):
     8         # 获取当前访问的页面
     9         url = request.path
    10 
    11         # 当前访问的路径id
    12         request.current_menu_id = None
    13 
    14         # 路径导航(面包线导航)的列表
    15         request.breadcrumb_list = [{'title': '首页', 'url': '/index/'}]
    16 
    17         # 白名单
    18         for i in settings.WHITE_LIST:
    19             # match 匹配上得到一个对象,匹配不上返回None
    20             if re.match(i, url):
    21                 return
    22         # 获取登录状态
    23         is_login = request.session['is_login']
    24         # 没有登录跳转登录页面
    25         if not is_login:
    26             return redirect('login')
    27 
    28         # 免认证
    29         for i in settings.NO_PERMISSION_LIST:
    30             # match 匹配上得到一个对象,匹配不上返回None
    31             if re.match(i, url):
    32                 return
    33 
    34         # 获取当前用户的权限, 要用get去拿,没有显示None,[]就会报错
    35         permission_dict = request.session.get(settings.PERMISSION_SESSION_KEY)
    36         # print(permission_list)
    37         # 权限的校验
    38         for permission in permission_dict.values():
    39             # print('>>>>',permission)
    40             if re.match(f'^{permission.get("url")}$', url):
    41 
    42                 pid = permission.get('pid')
    43                 id = permission.get('id')
    44                 pname = permission.get('pname')  # 路径导航改成pname
    45                 if pid:
    46                     # 当前访问的是添加编辑的功能
    47                     request.current_menu_id = pid   # 用request才能传过去
    48 
    49                     # 当点击添加或者编辑的时候就走的这里
    50                     parent = permission_dict[pname]
    51                     request.breadcrumb_list.append({'url': parent['url'], 'title': parent['title']})
    52 
    53                 else:
    54                     # 访问的是二级菜单
    55                     request.current_menu_id = id
    56  
    57                     # 如果没有pid就证明是二级菜单
    58                 request.breadcrumb_list.append({'url': permission['url'], 'title': permission['title']})
    59                 return
    60         # 没有匹配成功
    61         return HttpResponse('你的level不够!!')
    改成name后的权限验证中间件

           9 . 自定义过滤器

      

      

      

     

  • 相关阅读:
    iOS 9音频应用播放音频之第一个ios9音频实例2
    隐写术: 基地组织如何用视频隐藏绝密文档?
    stm32 Fatfs 读写SD卡
    STM32应用笔记转载
    STM32-NVIC中断管理实现[直接操作寄存器]
    FatFs源码剖析
    STM32固件库详解(转)
    Arduino线程库ProtoThreads
    ARM9(TQ2440)裸机代码分享
    将USBASP改造成STK502编程器(转)
  • 原文地址:https://www.cnblogs.com/attila/p/10571867.html
Copyright © 2011-2022 走看看