權限組件(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>

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM