• rbac组件之动态二级菜单之路径导航


    在之前的版本中,左上角路径导航在html页面写死了,如:

     那么我们需要做一个根据用户的不同操作从而实现路径导航的自动变化,如:

     第一步:在权限初始化的时候,对ORM取出的数据以及权限数据信息进行更改

    from django.conf import settings
    
    
    def init_permission(current_user, request):
        permission_queryset = current_user.roles.filter(
            permissions__isnull=False,
        ).values(
            "permissions__id",  # 二级菜单id
            "permissions__url",  # 二级菜单url
            "permissions__title",  # 二级菜单名称
            "permissions__menu__id",  # 一级菜单ID
            "permissions__menu__title",  # 一级菜单名称
            "permissions__menu__icon",  # 一级菜单图标
            "permissions__pid_id",  # 非菜单url的自关联pid值,如果是二级菜单那么该字段值为空
            "permissions__pid__title",  # 路径导航
            "permissions__pid__url",  # 路径导航
        ).distinct()
        permission_list = []  # 存放用户的权限数据信息
        menu_dict = {}  # 存放菜单信息
        for item in permission_queryset:
            # 权限信息数据结构变为列表套字典
            permission_list.append(
                {
                    "id": item["permissions__id"],  # 如果是二级菜单,那么需要用到此字段与菜单信息进行比较
                    "url": item["permissions__url"],
                    "title": item["permissions__title"],  # 路径导航
                    "pid": item["permissions__pid_id"],  # 如果此字段为空,那么说明该url是二级菜单;如果不为空,那么需要用此字段与菜单信息进行比较
                    "p_title": item["permissions__pid__title"],  # 路径导航
                    "p_url": item["permissions__pid__url"],  # 路径导航
                }
            )
            menu_id = item["permissions__menu__id"]  # 取到二级菜单所对应的一级菜单的id,如果不能做二级菜单的,那么这个字段值是null
            if not menu_id:
                continue
            node = {
                "id": item["permissions__id"],
                "title": item["permissions__title"],
                "url": item["permissions__url"],
            }  # 二级菜单数据信息,方便后续添加
            if menu_id in menu_dict:
                menu_dict[menu_id]["children"].append(node)  # 如果一级菜单已经存在,那么直接添加二级菜单数据信息即可
            else:
                # 如果一级菜单不存在,那么还需要添加一级菜单的数据信息和二级菜单的数据信息
                menu_dict[menu_id] = {
                    "title": item["permissions__menu__title"],
                    "icon": item["permissions__menu__icon"],
                    "children": [node, ],
                }
        print(permission_list)
        request.session[settings.PERMISSION_SESSION_KEY] = permission_list
        request.session[settings.MENU_SESSION_KEY] = menu_dict
    
    
    """
    权限信息
    permission_list = [
                        {'id': 1, 'url': '/customer/list/', 'title': '客户列表', 'pid': None, 'p_title': None, 'p_url': None},
                        {'id': 2, 'url': '/customer/add/', 'title': '添加客户', 'pid': 1, 'p_title': '客户列表', 'p_url': '/customer/list/'},
                        {'id': 3, 'url': '/customer/list/(?P<cid>\\d+)/', 'title': '删除客户', 'pid': 1, 'p_title': '客户列表', 'p_url': '/customer/list/'},
                        {'id': 4, 'url': '/customer/edit/(?P<cid>\\d+)/', 'title': '修改客户', 'pid': 1, 'p_title': '客户列表', 'p_url': '/customer/list/'},
                        {'id': 5, 'url': '/customer/import/', 'title': '批量导入', 'pid': 1, 'p_title': '客户列表', 'p_url': '/customer/list/'},
                        {'id': 6, 'url': '/customer/tpl/', 'title': '下载模板', 'pid': 1, 'p_title': '客户列表', 'p_url': '/customer/list/'},
                        {'id': 7, 'url': '/payment/list/', 'title': '账单列表', 'pid': None, 'p_title': None, 'p_url': None},
                        {'id': 8, 'url': '/payment/add/', 'title': '添加账单', 'pid': 7, 'p_title': '账单列表', 'p_url': '/payment/list/'},
                        {'id': 9, 'url': '/payment/del/(?P<pid>\\d+)/', 'title': '删除账单', 'pid': 7, 'p_title': '账单列表', 'p_url': '/payment/list/'},
                        {'id': 10, 'url': '/payment/edit/(?P<pid>\\d+)/', 'title': '修改账单', 'pid': 7, 'p_title': '账单列表', 'p_url': '/payment/list/'}
                        ]
    菜单信息
    menu_dict = {'1': {
                        'title': '信息管理', 
                        'icon': 'fa-camera-retro',
                        'children': [{'id': 1, 'title': '客户列表', 'url': '/customer/list/'}]},
                '2': {
                        'title': '用户管理', 
                        'icon': 'fa-fire',
                        'children': [{'id': 7, 'title': '账单列表', 'url': '/payment/list/'}]}}
    """

    第二步:在中间件新建一个默认列表,列表第一个数据为{"title": "首页", "url": "#"},然后基于此列表再添加路径,对权限信息中的pid进行判断,如果为空,则加一个,如果不为空,则加两个(一个是二级菜单,一个是当前操作的url对应的title)

    from django.utils.deprecation import MiddlewareMixin
    from django.conf import settings
    import re
    from django.shortcuts import HttpResponse
    
    
    class RbacMiddleware(MiddlewareMixin):
        def process_request(self, request):
            current_url = request.path_info
            for url in settings.VALID_URL_LIST:
                if re.match(url, current_url):
                    return None
            permission_list = request.session.get(settings.PERMISSION_SESSION_KEY)
            if not permission_list:
                return HttpResponse("未获取到用户权限信息,请重新登录...")
            flag = False
            url_record = [
                {"title": "首页", "url": "#"},
            ]  # 路径导航列表
            for url in permission_list:
                reg = "^%s$" % url["url"]
                if re.match(reg, current_url):
                    flag = True
                    request.current_selected_permission = url["pid"] or url["id"]  # pid不为空,那么值为pid;pid为空,那么值为id
                    # 路径导航
                    if not url["pid"]:
                        url_record.extend(
                            [{"title": url["title"], "url": url["url"], "class": "active"}]
                        )
                    else:
                        url_record.extend(
                            [
                                {"title": url["p_title"], "url": url["p_url"]},
                                {"title": url["title"], "url": url["url"], "class": "active"},
                            ]
                        )
                    request.url_record = url_record  # 路径导航
                    break
            if not flag:
                return HttpResponse("你无权访问,请速速撤离...")
    
    
    """
    permission_list = [
                        {'id': 1, 'url': '/customer/list/', 'title': '客户列表', 'pid': None, 'p_title': None, 'p_url': None},
                        {'id': 2, 'url': '/customer/add/', 'title': '添加客户', 'pid': 1, 'p_title': '客户列表', 'p_url': '/customer/list/'},
                        {'id': 3, 'url': '/customer/list/(?P<cid>\\d+)/', 'title': '删除客户', 'pid': 1, 'p_title': '客户列表', 'p_url': '/customer/list/'},
                        {'id': 4, 'url': '/customer/edit/(?P<cid>\\d+)/', 'title': '修改客户', 'pid': 1, 'p_title': '客户列表', 'p_url': '/customer/list/'},
                        {'id': 5, 'url': '/customer/import/', 'title': '批量导入', 'pid': 1, 'p_title': '客户列表', 'p_url': '/customer/list/'},
                        {'id': 6, 'url': '/customer/tpl/', 'title': '下载模板', 'pid': 1, 'p_title': '客户列表', 'p_url': '/customer/list/'},
                        {'id': 7, 'url': '/payment/list/', 'title': '账单列表', 'pid': None, 'p_title': None, 'p_url': None},
                        {'id': 8, 'url': '/payment/add/', 'title': '添加账单', 'pid': 7, 'p_title': '账单列表', 'p_url': '/payment/list/'},
                        {'id': 9, 'url': '/payment/del/(?P<pid>\\d+)/', 'title': '删除账单', 'pid': 7, 'p_title': '账单列表', 'p_url': '/payment/list/'},
                        {'id': 10, 'url': '/payment/edit/(?P<pid>\\d+)/', 'title': '修改账单', 'pid': 7, 'p_title': '账单列表', 'p_url': '/payment/list/'}
                        ]
    """

    第三步:写inclusion_tag

    from django.template import Library
    from django.conf import settings
    import re
    from collections import OrderedDict
    
    
    register = Library()
    
    
    @register.inclusion_tag("rbac/url_record.html")
    def url_record(request):
        return {"url_record": request.url_record}

    第四步:写inclusion_tag返回的html

    <div>
        <ol class="breadcrumb no-radius no-margin" style="border-bottom: 1px solid #ddd;">
            {% for item in url_record %}
                {% if item.class %}
                    <li class="{{ item.class }}">{{ item.title }}</li>
                    {% else %}
                        <li><a href="{{ item.url }}">{{ item.title }}</a></li>
                {% endif %}
            {% endfor %}
        </ol>
    </div>

    第五步:前端应用该inclusion_tag

    {% load rbac %}
    
    {% url_record request %}

    链接:https://pan.baidu.com/s/19DzXcRUPa8ockyqTRE72WA
    提取码:abab

  • 相关阅读:
    hrbust 1788
    poj2299 ( bit )
    LA3027(并查集)
    hdu1166 (bit)
    hdu1598(并查集)
    cdoj1215 (并查集)
    hdu2643 ( 第二类斯特灵数 )
    hdu3625 ( 第一类斯特灵数 )
    Uva10066
    怎么处理sqlserver2017部署在winowsDocker上时区无法修改成功的方式,并且可以多创建新的容器调用简单的方式直接使用!
  • 原文地址:https://www.cnblogs.com/xuewei95/p/15859115.html
Copyright © 2020-2023  润新知