• 权限组件(4):给动态菜单增加面包屑导航


    效果图:

    一、在初始化权限的时候增加二级菜单的标题和url

    这么做是为了在中间件中把二级菜单和具体权限的标题、url都储存起来
    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__pid__title',  # +
            'permissions__pid__url',    # + 
            'permissions__menu_id',
            'permissions__menu__title',
            'permissions__menu__icon',
        )
    
        permission_list = []
    
        menu_dict = {}
    
        for item in permission_menu_queryset:
            permission_list.append({
                'id': item['permissions__id'],
                'title': item['permissions__title'],
                'url': item['permissions__url'],
                'pid': item['permissions__pid_id'],  # + 
                'p_title': item['permissions__pid__title'],    # +
                'p_url': item['permissions__pid__url'],
            })
    
            menu_id = item['permissions__menu_id']
    
            if not menu_id:
                continue
    
            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

    二、中间件处理

    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
    
            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
    
            url_record = [
                {'title': '首页', 'url': '#'}
            ]
            for item in permission_list:
                regex = '^%s$' % item['url']
                if re.match(regex, current_path):
                    has_permission = True
                    request.current_selected_permission = item['pid'] or item['id']
                    if not item['pid']:  # 选中的是二级菜单,这时候是没有pid的,所以就没有p_title
                        url_record.extend([
                            {'title': item['title'], 'url': item['url'], 'class': 'active'}
                        ])
                    else:  # 选中的是具体权限,有pid和p_title。给具体权限加上class。
                        url_record.extend([
                            {'title': item['p_title'], 'url': item['p_url']},
                            {'title': item['title'], 'url': item['url'], 'class': 'active'},
                        ])
                    request.breadcrumb = url_record  # 通过request,把储存信息传给用户
                    break
    
            if not has_permission:
                return HttpResponse('未获取权限')

     注意:

    • 选中的是二级菜单时,只要给列表加上二级菜单就标题和url就可以,这时候是没有pid和p_title的。直接给二级菜单加上class就可以。
    • 选中具体权限时,它是有pid的,要给列表加上二级菜单的标题和url。给具体权限加上class

    class在页面会显示灰色效果。

     

    三、模板处理

    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/breadcrumb.html')
    def breadcrumb(request):
        return {'record_list': request.breadcrumb}

    rbac/templates/rbac/breadcrumb.html

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

    如果有class,就说明是被用户选中的二级菜单或url,反之,就给一个可以点击的a标签

    在layout.html页面引入面包屑导航

        <div class="right-body">
    
            {% breadcrumb request %}  <!-- + -->
    
            {% block content %} {% endblock %}
        </div>

  • 相关阅读:
    C++ 重载操作符- 01 简单的入门
    C++ 析构函数
    Auto Control 001 自动控制的一般概念
    C++ 友元
    安装 SQL Server 2014 Express
    关闭是否只查看安全传送的网页内容提示框 和 是否允许运行软件,如ActiveX控件和插件提示框
    Python 网络爬虫 010 (高级功能) 解析 robots.txt 文件
    2019-06-12 Java学习日记之JDBC
    2019-06-11 Java学习日记之Bootstrap
    2019-06-10 Java学习日记之JQuery
  • 原文地址:https://www.cnblogs.com/lshedward/p/10497669.html
Copyright © 2020-2023  润新知