權限組件(3):非菜單默認選中
阿新 • • 發佈:2019-03-08
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
說明:拿客戶列表來舉例:
id | title | url | menu_id | pid |
---|---|---|---|---|
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):非菜單默認選中