一、非菜单权限对应的一级菜单展开

  需求:客户列表和账单列表页面中都有添加按钮,当点击添加客户(或编辑客户、删除客户)时,客户列表所属的一级菜单展开,当点击添加账单(或编辑账单、删除账单)时,账单列表所属的一级菜单展开。

1、permission表新增一个pid字段,表示非菜单权限的父级菜单权限id,permission模型类如下:

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

2、修改权限列表数据结构,注入session,setsession.py中代码如下:

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

3、因修改了权限列表的数据结构,所以中间件校验权限也需要修改,中间件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('无权访问')

4、修改my_tags.py文件,代码如下:

@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字段,建立菜单权限和非菜单权限之间的关系,来控制访问某一非菜单权限时,其对应的菜单权限展开。

二、面包屑导航

  需求:实现面包屑导航

1、修改中间件,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') # 路径导航列表
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('无权访问')

2、公共模板页面base.html中面包屑导航位置的代码如下:

<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>

Django - 权限(5)- 非菜单权限对应的一级菜单展开、面包屑导航的更多相关文章

  1. ASP.NET的面包屑导航控件、树形导航控件、菜单控件

    原文:http://blog.csdn.net/pan_junbiao/article/details/8579293 ASP.NET的面包屑导航控件.树形导航控件.菜单控件. 1. 面包屑导航控件— ...

  2. vue实现菜单权限控制

    大家在做后台管理系统时一般都会涉及到菜单的权限控制问题.当然解决问题的方法无非两种——前端控制和后端控制.我们公司这边的产品迭代速度较快,所以我们是从前端控制路由迭代到后端控制路由.下面我会分别介绍这 ...

  3. vue路由菜单权限设置就button权限设置

    路由权限的设计思路: 首先,我们的需要校验权限的路由的 url,全部由后端返回,后端会返回当前用户的路由树数组.前端在进入页面前请求接口,把数据拿到: 其次,前端会维护一个路由映射组件的列表,如果路由 ...

  4. java查询几个菜单下的所有下级菜单

    需求: 假如有几个一级菜单,一级菜单下面有几个二级菜单,二级菜单下又还有三级菜单.现在要求一级菜单里面的几个设置为无效,将不显示在前端.现在需要的是查询出一级菜单下面所有的菜单,包括二级,三级菜单 原 ...

  5. python 全栈开发,Day108(客户管理之权限控制,客户管理之动态"一级"菜单,其他应用使用rbac组件,django static文件的引入方式)

    一.客户管理之权限控制 昨天的作业,有很多不完善的地方 下载代码,基本实现权限验证 https://github.com/987334176/luffy_permission/archive/v1.2 ...

  6. django 菜单权限

    一.什么是权限 能做哪些事情,不能做哪些事情,可以做的权限 二.设计权限 思路: web应用中,所谓的权限,其实就是一个用户能够访问的url,通过对用户访问的url进行控制,从而实现对用户权限的控制. ...

  7. django中非菜单权限的归属

    非菜单权限的归属 :         1.设置表结构 : 在权限表中添加自连接的外键patent,parent_id连接permission表的id,可为空,当有parent_id时,说明它是一个普通 ...

  8. django 权限设置 左侧菜单点击显示,面包屑

    1.左侧菜单点击显示 就是在点击的时候保留点击的功能 方法. 1.加入新的字段,pid来判断 class Permission(models.Model): """ 权限 ...

  9. pc vue 项目中的菜单权限控制

    在pc 管理系统这种类型的产品,通常会涉及到账号权限的控制,不同的账号权限能浏览的功能模块是不同的,对应侧边栏菜单模块的显示也会不同. 场景一.(电商类管理系统) 登录 登录后,依次获取账号 toke ...

随机推荐

  1. jsp的页面包含——静态包含、动态包含

    一.静态包含:包含的文件可以是jsp文件.html文件.文本文件或者一段java代码.<%@ include file="要包含的文件路径"%> 实质是先将所包含的文件 ...

  2. redis命令_ZREM

    ZREM key member [member ...] 移除有序集 key 中的一个或多个成员,不存在的成员将被忽略. 当 key 存在但不是有序集类型时,返回一个错误. 在 Redis 2.4 版 ...

  3. JavaScript学习日志(1)

    javascript用法: 1.HTML中的脚本必须位于<script>与</script>标签之间,可被放置在HTML页面的<body>和<head> ...

  4. Compiler Error C2872: ambiguous symbol

    参考资料:http://blog.csdn.net/greytree/article/details/354530 刚才写的程序报错ERROR C2872(CL.exe)原因很简单 ZThread有定 ...

  5. ubox及日志管理

    ubox是openwrt的帮助工具箱,位于代码package/system/ubox下, CMakeLists.txt kmodloader.c log/ lsbloader.c validate/ ...

  6. Ubuntu安装新版本nodejs的5种姿势

    引言: 写这篇文章之前,关于ubuntu14.04(Trusty)默认安装的NodeJS版本是0.10.25百思不解(什么鬼,哪一年的NodeJS) 写这篇文章之时,NodeJS的LTS版本号都已经1 ...

  7. poj2391 Ombrophobic Bovines 拆点+二分法+最大流

    /** 题目:poj2391 Ombrophobic Bovines 链接:http://poj.org/problem?id=2391 题意:有n块区域,第i块区域有ai头奶牛,以及一个可以容纳bi ...

  8. Xcode 调试方法总结

    前言:编写代码过程中出现错误.异常是不可避免的.通常我们都需要进行大量的调试去寻找.解决问题.这时,熟练掌握调试技巧将很大程度上的提高工作效率.接下来就说说开发过程中Xcode的调试方法. 1. En ...

  9. windows下GVIM的配置(vimrc)

    学习python时想要在gvim中配置python的编译环境,网上找到一个比较好用的vimrc配置,保存下来以备下次有需要. set encoding=utf-8 set termencoding=u ...

  10. 安装python各类工具包、IDE以及著名开源模块如kaldi等的简单总结

    在学习一门语言或者使用一个著名的开源工具时,搭建环境是非常重要的一步,在环境搭建的过程中往往要踩很多坑.昨天一不小心把电脑操作系统整坏了,搞了个通宵算是搞定了,把win10系统重装回win7,但之前搭 ...