需求:客戶列表和帳單列表頁面中都有添加按鈕,當點擊添加客戶(或編輯客戶、刪除客戶)時,客戶列表所屬的一級菜單展開,當點擊添加帳單(或編輯帳單、刪除帳單)時,帳單列表所屬的一級菜單展開。html
一、permission表新增一個pid字段,表示非菜單權限的父級菜單權限id,permission模型類以下:django
class Permission(models.Model): """ 權限表 """ url = models.CharField(verbose_name='含正則的URL', max_length=32) title = models.CharField(verbose_name='標題', max_length=32) menu = models.ForeignKey(verbose_name='標題', to="Menu", on_delete=models.CASCADE, null=True) name = models.CharField(verbose_name='url別名', max_length=32, default="") pid = models.ForeignKey("self", on_delete=models.CASCADE, null=True, verbose_name='父權限') def __str__(self): return self.title
二、修改權限列表數據結構,注入session,setsession.py中代碼以下:session
def initial_session(user_obj, request): """ 將當前登陸人的全部權限url列表和 本身構建的全部菜單權限字典和 權限表name字段列表注入session :param user_obj: 當前登陸用戶對象 :param request: 請求對象HttpRequest """ # 查詢當前登陸人的全部權限列表 ret = Role.objects.filter(user=user_obj).values('permissions__url', 'permissions__title', 'permissions__name', 'permissions__pk', 'permissions__pid', 'permissions__menu__title', 'permissions__menu__icon', 'permissions__menu__id').distinct() permission_list = [] permission_names = [] permission_menu_dict = {} for item in ret: # 獲取用戶權限列表用於中間件中權限校驗,改變數據結構 permission_list.append({ 'url':item['permissions__url'], 'id':item['permissions__pk'], 'pid':item['permissions__pid'], 'title':item['permissions__title'] }) # 獲取權限表name字段用於動態顯示權限按鈕 permission_names.append(item['permissions__name']) menu_pk = item['permissions__menu__id'] if menu_pk: if menu_pk not in permission_menu_dict: permission_menu_dict[menu_pk] = { "menu_title": item["permissions__menu__title"], "menu_icon": item["permissions__menu__icon"], "children": [ { "title": item["permissions__title"], "url": item["permissions__url"], "pk": item["permissions__pk"] } ], } else: permission_menu_dict[menu_pk]["children"].append({ "title": item["permissions__title"], "url": item["permissions__url"], }) print('權限列表', permission_list) print('菜單權限', permission_menu_dict) # 將當前登陸人的權限列表注入session中 request.session['permission_list'] = permission_list # 將權限表name字段列表注入session中 request.session['permission_names'] = permission_names # 將當前登陸人的菜單權限字典注入session中 request.session['permission_menu_dict'] = permission_menu_dict
三、因修改了權限列表的數據結構,因此中間件校驗權限也須要修改,中間件middlewares.py代碼以下:數據結構
from django.utils.deprecation import MiddlewareMixin from django.shortcuts import redirect, HttpResponse import re class PermissionMiddleWare(MiddlewareMixin): def process_request(self, request): # 設置白名單放行 for reg in ["/login/", "/admin/*"]: ret = re.search(reg, request.path) if ret: return None # 檢驗是否登陸 user_id = request.session.get('user_id') if not user_id: return redirect('/login/') # 檢驗權限 permission_list = request.session.get('permission_list') for item in permission_list: reg = '^%s$' % item["url"] ret = re.search(reg, request.path) if ret: show_id = item["pid"] or item["id"] request.show_id = show_id # 給request對象添加一個屬性 return None return HttpResponse('無權訪問')
四、修改my_tags.py文件,代碼以下:app
@register.inclusion_tag("menu.html") def get_menu_styles(request): permission_menu_dict = request.session.get("permission_menu_dict") print("permission_menu_dict", permission_menu_dict) for val in permission_menu_dict.values(): for item in val["children"]: val["class"] = "hide" # /customer/ # /customer/edit/3 if request.show_id == item["pk"]: val["class"] = "" return {"permission_menu_dict": permission_menu_dict}
總結:以前菜單權限和非菜單權限之間沒有關係,經過在權限表中添加pid字段,創建菜單權限和非菜單權限之間的關係,來控制訪問某一非菜單權限時,其對應的菜單權限展開。ide
需求:實現麪包屑導航url
一、修改中間件,middlewares.py中代碼以下:spa
from django.utils.deprecation import MiddlewareMixin from django.shortcuts import redirect, HttpResponse import re class PermissionMiddleWare(MiddlewareMixin): def process_request(self, request): # 設置白名單放行 for reg in ["/login/", "/admin/*"]: ret = re.search(reg, request.path) if ret: return None # 檢驗是否登陸 user_id = request.session.get('user_id') if not user_id: return redirect('/login/') # 檢驗權限 permission_list = request.session.get('permission_list') # 路徑導航列表 request.breadcrumb = [ { "title": "首頁", "url": "/" }, ] for item in permission_list: reg = '^%s$' % item["url"] ret = re.search(reg, request.path) if ret: show_id = item["pid"] or item["id"] request.show_id = show_id # 給request對象添加一個屬性 # 肯定麪包屑列表 if item["pid"]: ppermission = Permission.objects.filter(pk=item["pid"]) .first() request.breadcrumb.extend( [{ # 父權限字典 "title": ppermission.title, "url": ppermission.url }, { # 子權限字典 "title": item["title"], "url": request.path }] ) else: request.breadcrumb.append( { "title": item["title"], "url": item["url"] } ) return None return HttpResponse('無權訪問')
二、公共模板頁面base.html中麪包屑導航位置的代碼以下:code
<div> <ol class="breadcrumb no-radius no-margin"> {% for item in request.breadcrumb %} <li><a href="{{ item.url }}">{{ item.title }}</a></li> {% endfor %} </ol> </div>