1. 程式人生 > >權限組件(3):非菜單默認選中

權限組件(3):非菜單默認選中

roles rbo shortcut 菜單 lin end cut line audio

一、在權限表裏新建一個自關聯的字段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/(?P\d+)/ null 1
4 刪除客戶 /customer/del/(?P\d+)/ 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

權限組件(3):非菜單默認選中