我想要的是, 这里的显示内容,可以随着。 我点击的不同而展示 不同的东西。
思路:
1. 登录的时候, 在session中保存下。 当前用户所有的权限url 和 每一条url 的 所属那一条url。
2. 在request 对象中, 保存上。url的浏览记录。(就是 用户当前访问的url 和 他所属的父级 url)
3. 直接在 模板,进行渲染。
session的修改:
def init_permission(current_user, request): ''' 二级菜单,实现 :param current_user: 当前请求 用户对象 :param request: 当前请求 数据 :return: ''' # 2. 权限 初始化 # 根据当前用户信息,获取当前用户所拥有的所有的权限(queryset对象 是不能直接放入,session中的) permission_queryset = current_user.roles.filter(permissions__isnull=False) .values("permissions__id", "permissions__url", "permissions__title", "permissions__pid_id", "permissions__pid__title", "permissions__pid__url", "permissions__menu_id", "permissions__menu__icon", "permissions__menu__title", ).distinct() # 取出了 当前url的所有信息; 当前url所属pid的所有信息; 当前url 对应的一级菜单所有信息。 # 获取权限 和 菜单信息。 权限放在权限列表,菜单放在菜单列表 menu_dict = {} permission_list = [] for item in permission_queryset: url_dict = { # 将url自己的信息 和 所属的父级url所有信息, 进行保存 "id": item.get("permissions__id"), "title" : item.get("permissions__title"), "url": item.get("permissions__url"), "paren_id": item.get("permissions__pid_id"), "paren_title": item.get("permissions__pid__title"), "paren_url": item.get("permissions__pid__url"), } permission_list.append(url_dict) menu_id = item.get("permissions__menu_id") if not menu_id: continue node = {"id": item.get("permissions__id"), "title": item.get("permissions__title"), "url": item.get("permissions__url")} if menu_id in menu_dict: menu_dict[menu_id]["children"].append(node) else: menu_dict[menu_id] = { "title": item.get("permissions__menu__title"), "icon": item.get("permissions__menu__icon"), "children": [node] } request.session[settings.PERMISSIONS_SESSION_KEY] = permission_list request.session[settings.MENU_SESSION_KEY] = menu_dict
rbac 中间件, 为request对象 添加url_record url记录列表。
class RbacMiddleware(MiddlewareMixin):
'''用户权限信息的校验'''
def process_request(self, request):
'''当用户请求进入时 触发执行'''
'''
1. 获取当前用户请求的url
2. 获取当前用户在session中保存的 权限列表 [......]
3. 当前请求url 在 session中, 就可以,进行访问
'''
current_url = request.path_info
for valid_url in settings.VALID_URL_LIST:
if re.match(valid_url, current_url): # 白名单中的url 无需权限验证
return None
permission_list = request.session.get(settings.PERMISSIONS_SESSION_KEY)
# print(permission_list)
# print(current_url)
if not permission_list:
'''用户未登录前 session为空, 所以直接返回就好了'''
return HttpResponse("您没有访问权限...请联系管理员")
flag = False
# 搞一个导航条的展示:
url_record = [
{"title": "首页", "url": "#"}
]
for item in permission_list:
reg = "^%s$" % item.get("url") # 正则匹配match 都是从其实开始匹配,但是没有限定结束。
# 所以要给当前的url 添加 ^ $ 开始和终止符。严格的匹配当前的url 是否与 列表中的url 可以匹配成功
if re.match(reg, current_url):
flag = True
request.current_selected_permission = item.get("paren_id") or item.get("id")
# 判断当前访问的url 它的 paren_id 是否为空。 如果未空,表示用户当前访问的,是一个子菜单。 url_record中添加上他自己的本身的 标题和url 就好。
# 如果当前访问的url 它的 paren_id 不为空, 表示用户当前访问的,是子菜单下的某一个功能。 url_record中除添加上他自己的本身的 title 和 url之外, 还应该添加上它 父级也就是它所属的那条 url的 title 和 url 信息。
if not item.get("paren_id"):
url_record.extend([{"title": item.get("title"), "url": item.get("url"), "class": "active"}])
else:
url_record.extend([
{"title": item.get("paren_title"), "url": item.get("paren_title")},
{"title": item.get("title"), "url": item.get("url"), "class": "active"},
])
request.url_record = url_record
break
if not flag:
return HttpResponse("无权访问")
最后就是,模板的渲染:
渲染方式一:
因为,我已经在。 列表中保存了。 每一个url 的 title 和 url。 所以直接在模板中 进行 for循环:
<div> <ol class="breadcrumb no-radius no-margin" style="border-bottom: 1px solid #ddd;"> {% for item in request.url_record %} <li><a href="{{ item.url }}">{{item.title}}</a></li> {% endfor %} </ol> </div>
渲染方式二: 还是使用inclusion_tag 进行实现。 业务app的 模板中只需要调用, 自定义的模板语法就好!
@register.inclusion_tag("rbac/url_record.html")
def url_record(request):
return {"record_list":request.url_record}
<div> <ol class="breadcrumb no-radius no-margin" style="border-bottom: 1px solid #ddd;"> {% for item in record_list %} {% if item.class %} <li class="active">{{ item.title }}</li> {% else %} <li><a href="{{ item.url }}">{{ item.title }}</a></li> {% endif %} {% endfor %} </ol> </div>