在之前的版本中,左上角路径导航在html页面写死了,如:
那么我们需要做一个根据用户的不同操作从而实现路径导航的自动变化,如:
第一步:在权限初始化的时候,对ORM取出的数据以及权限数据信息进行更改
from django.conf import settings def init_permission(current_user, request): permission_queryset = current_user.roles.filter( permissions__isnull=False, ).values( "permissions__id", # 二级菜单id "permissions__url", # 二级菜单url "permissions__title", # 二级菜单名称 "permissions__menu__id", # 一级菜单ID "permissions__menu__title", # 一级菜单名称 "permissions__menu__icon", # 一级菜单图标 "permissions__pid_id", # 非菜单url的自关联pid值,如果是二级菜单那么该字段值为空 "permissions__pid__title", # 路径导航 "permissions__pid__url", # 路径导航 ).distinct() permission_list = [] # 存放用户的权限数据信息 menu_dict = {} # 存放菜单信息 for item in permission_queryset: # 权限信息数据结构变为列表套字典 permission_list.append( { "id": item["permissions__id"], # 如果是二级菜单,那么需要用到此字段与菜单信息进行比较 "url": item["permissions__url"], "title": item["permissions__title"], # 路径导航 "pid": item["permissions__pid_id"], # 如果此字段为空,那么说明该url是二级菜单;如果不为空,那么需要用此字段与菜单信息进行比较 "p_title": item["permissions__pid__title"], # 路径导航 "p_url": item["permissions__pid__url"], # 路径导航 } ) menu_id = item["permissions__menu__id"] # 取到二级菜单所对应的一级菜单的id,如果不能做二级菜单的,那么这个字段值是null if not menu_id: continue node = { "id": item["permissions__id"], "title": item["permissions__title"], "url": item["permissions__url"], } # 二级菜单数据信息,方便后续添加 if menu_id in menu_dict: menu_dict[menu_id]["children"].append(node) # 如果一级菜单已经存在,那么直接添加二级菜单数据信息即可 else: # 如果一级菜单不存在,那么还需要添加一级菜单的数据信息和二级菜单的数据信息 menu_dict[menu_id] = { "title": item["permissions__menu__title"], "icon": item["permissions__menu__icon"], "children": [node, ], } print(permission_list) request.session[settings.PERMISSION_SESSION_KEY] = permission_list request.session[settings.MENU_SESSION_KEY] = menu_dict """ 权限信息 permission_list = [ {'id': 1, 'url': '/customer/list/', 'title': '客户列表', 'pid': None, 'p_title': None, 'p_url': None}, {'id': 2, 'url': '/customer/add/', 'title': '添加客户', 'pid': 1, 'p_title': '客户列表', 'p_url': '/customer/list/'}, {'id': 3, 'url': '/customer/list/(?P<cid>\\d+)/', 'title': '删除客户', 'pid': 1, 'p_title': '客户列表', 'p_url': '/customer/list/'}, {'id': 4, 'url': '/customer/edit/(?P<cid>\\d+)/', 'title': '修改客户', 'pid': 1, 'p_title': '客户列表', 'p_url': '/customer/list/'}, {'id': 5, 'url': '/customer/import/', 'title': '批量导入', 'pid': 1, 'p_title': '客户列表', 'p_url': '/customer/list/'}, {'id': 6, 'url': '/customer/tpl/', 'title': '下载模板', 'pid': 1, 'p_title': '客户列表', 'p_url': '/customer/list/'}, {'id': 7, 'url': '/payment/list/', 'title': '账单列表', 'pid': None, 'p_title': None, 'p_url': None}, {'id': 8, 'url': '/payment/add/', 'title': '添加账单', 'pid': 7, 'p_title': '账单列表', 'p_url': '/payment/list/'}, {'id': 9, 'url': '/payment/del/(?P<pid>\\d+)/', 'title': '删除账单', 'pid': 7, 'p_title': '账单列表', 'p_url': '/payment/list/'}, {'id': 10, 'url': '/payment/edit/(?P<pid>\\d+)/', 'title': '修改账单', 'pid': 7, 'p_title': '账单列表', 'p_url': '/payment/list/'} ] 菜单信息 menu_dict = {'1': { 'title': '信息管理', 'icon': 'fa-camera-retro', 'children': [{'id': 1, 'title': '客户列表', 'url': '/customer/list/'}]}, '2': { 'title': '用户管理', 'icon': 'fa-fire', 'children': [{'id': 7, 'title': '账单列表', 'url': '/payment/list/'}]}} """
第二步:在中间件新建一个默认列表,列表第一个数据为{"title": "首页", "url": "#"},然后基于此列表再添加路径,对权限信息中的pid进行判断,如果为空,则加一个,如果不为空,则加两个(一个是二级菜单,一个是当前操作的url对应的title)
from django.utils.deprecation import MiddlewareMixin from django.conf import settings import re from django.shortcuts import HttpResponse class RbacMiddleware(MiddlewareMixin): def process_request(self, request): current_url = request.path_info for url in settings.VALID_URL_LIST: if re.match(url, current_url): return None permission_list = request.session.get(settings.PERMISSION_SESSION_KEY) if not permission_list: return HttpResponse("未获取到用户权限信息,请重新登录...") flag = False url_record = [ {"title": "首页", "url": "#"}, ] # 路径导航列表 for url in permission_list: reg = "^%s$" % url["url"] if re.match(reg, current_url): flag = True request.current_selected_permission = url["pid"] or url["id"] # pid不为空,那么值为pid;pid为空,那么值为id # 路径导航 if not url["pid"]: url_record.extend( [{"title": url["title"], "url": url["url"], "class": "active"}] ) else: url_record.extend( [ {"title": url["p_title"], "url": url["p_url"]}, {"title": url["title"], "url": url["url"], "class": "active"}, ] ) request.url_record = url_record # 路径导航 break if not flag: return HttpResponse("你无权访问,请速速撤离...") """ permission_list = [ {'id': 1, 'url': '/customer/list/', 'title': '客户列表', 'pid': None, 'p_title': None, 'p_url': None}, {'id': 2, 'url': '/customer/add/', 'title': '添加客户', 'pid': 1, 'p_title': '客户列表', 'p_url': '/customer/list/'}, {'id': 3, 'url': '/customer/list/(?P<cid>\\d+)/', 'title': '删除客户', 'pid': 1, 'p_title': '客户列表', 'p_url': '/customer/list/'}, {'id': 4, 'url': '/customer/edit/(?P<cid>\\d+)/', 'title': '修改客户', 'pid': 1, 'p_title': '客户列表', 'p_url': '/customer/list/'}, {'id': 5, 'url': '/customer/import/', 'title': '批量导入', 'pid': 1, 'p_title': '客户列表', 'p_url': '/customer/list/'}, {'id': 6, 'url': '/customer/tpl/', 'title': '下载模板', 'pid': 1, 'p_title': '客户列表', 'p_url': '/customer/list/'}, {'id': 7, 'url': '/payment/list/', 'title': '账单列表', 'pid': None, 'p_title': None, 'p_url': None}, {'id': 8, 'url': '/payment/add/', 'title': '添加账单', 'pid': 7, 'p_title': '账单列表', 'p_url': '/payment/list/'}, {'id': 9, 'url': '/payment/del/(?P<pid>\\d+)/', 'title': '删除账单', 'pid': 7, 'p_title': '账单列表', 'p_url': '/payment/list/'}, {'id': 10, 'url': '/payment/edit/(?P<pid>\\d+)/', 'title': '修改账单', 'pid': 7, 'p_title': '账单列表', 'p_url': '/payment/list/'} ] """
第三步:写inclusion_tag
from django.template import Library from django.conf import settings import re from collections import OrderedDict register = Library() @register.inclusion_tag("rbac/url_record.html") def url_record(request): return {"url_record": request.url_record}
第四步:写inclusion_tag返回的html
<div> <ol class="breadcrumb no-radius no-margin" style="border-bottom: 1px solid #ddd;"> {% for item in url_record %} {% if item.class %} <li class="{{ item.class }}">{{ item.title }}</li> {% else %} <li><a href="{{ item.url }}">{{ item.title }}</a></li> {% endif %} {% endfor %} </ol> </div>
第五步:前端应用该inclusion_tag
{% load rbac %} {% url_record request %}
链接:https://pan.baidu.com/s/19DzXcRUPa8ockyqTRE72WA
提取码:abab