django 菜单权限
一.什么是权限
能做哪些事情,不能做哪些事情,可以做的权限
二.设计权限
思路:
web应用中,所谓的权限,其实就是一个用户能够访问的url,通过对用户访问的url进行控制,从而实现对用户权限的控制.
每个用户代表不同的的角色,每个角色具有不同的权限.
一个用户可以有多重角色,多个人也可以是一种角色(比如说一个公司可以有多个销售),所以说,用户与角色之间的关系是多对多的关系.
一个角色能够拥有多个权限,一个权限也可以分配给多个角色;所以说角色和权限的关系也是多对多的关系.
三.权限实现
建立表关系
具体代码如下:
from django.db import models class Menu(models.Model):
title = models.CharField(max_length=32)
icon = models.CharField(max_length=32)
weight = models.IntegerField(default=1, verbose_name='权重')
class Permission(models.Model):
"""
权限表
"""
title = models.CharField(max_length=32, verbose_name='标题')
url = models.CharField(max_length=32, verbose_name='权限') menu = models.ForeignKey(to='Menu',on_delete=models.CASCADE,default=0,blank=True,null=True)
pid = models.ForeignKey('self',on_delete=models.CASCADE,null=True,verbose_name='父权限') name = models.CharField(max_length=32, null=True, blank=True, unique=True) class Meta:
verbose_name_plural = '权限表'
verbose_name = '权限表' def __str__(self):
return self.title class Role(models.Model):
name = models.CharField(max_length=32, verbose_name='角色名称')
permissions = models.ManyToManyField(to='Permission', verbose_name='角色所拥有的权限', blank=True) def __str__(self):
return self.name class User(models.Model):
"""
用户表
"""
name = models.CharField(max_length=32, verbose_name='用户名')
password = models.CharField(max_length=32, verbose_name='密码')
roles = models.ManyToManyField(to='Role', verbose_name='用户所拥有的角色', blank=True) def __str__(self):
return self.name
获取权限信息
每次当用户一登录是,就应该获取当前的用户所拥有的所有权限信息.
当然了首先需要构建的应该是当前用户的权限列表中.构建出来之后将其存入到session中,以便于之后的权限校验
这里还需要构造出我们创建菜单想要的数据结构,以便于之后创建二级菜单.
然后我们构建出来的菜单数据结构和权限列表如下所示:
permission_list[{
'url': '/customer/',
'pid': None,
'title': '全部客户',
'id': 1
}, {
'url': '/customers/list/',
'pid': None,
'title': '共有客户',
'id': 2
}, {
'url': '/mycustomers/',
'pid': None,
'title': '我的客户',
'id': 3
}, {
'url': '/consult_records/',
'pid': None,
'title': '客户跟进记录',
'id': 4
}, {
'url': '/customer/count/',
'pid': None,
'title': '客户成单统计',
'id': 5
}, {
'url': '/enrollment/',
'pid': None,
'title': '报名情况',
'id': 6
}, {
'url': '/enrollment/add/',
'pid': 6,
'title': '添加报名记录',
'id': 7
}, {
'url': '/enrollment/edit/(\\d+)',
'pid': 6,
'title': '修改报名记录',
'id': 8
}, {
'url': '/ClassStudyRecord/list/',
'pid': None,
'title': '班级学习记录',
'id': 9
}, {
'url': '/ClassStudyRecord/add/',
'pid': 9,
'title': '添加学习记录',
'id': 10
}, {
'url': '/studentstudyrecord/edit/(\\d+)/',
'pid': 9,
'title': '添加记录',
'id': 11
}, {
'url': '/rbac/role/list/',
'pid': None,
'title': '角色管理',
'id': 12
}, {
'url': '/rbac/role/add/',
'pid': 12,
'title': '添加角色',
'id': 13
}, {
'url': '/rbac/role/edit/(\\d+)',
'pid': 12,
'title': '修改角色',
'id': 14
}, {
'url': '/rbac/role/del/(\\d+)',
'pid': 12,
'title': '删除角色',
'id': 15
}, {
'url': '/rbac/menu/list/',
'pid': None,
'title': '菜单管理',
'id': 16
}, {
'url': '/rbac/menu/add/',
'pid': 16,
'title': '添加目录',
'id': 17
}, {
'url': '/rbac/menu/edit/(\\d+)',
'pid': 16,
'title': '修改目录',
'id': 18
}, {
'url': '/rbac/permission/distrbute/',
'pid': None,
'title': '分配权限',
'id': 19
}, {
'url': '/rbac/permission/tree/',
'pid': 19,
'title': '权限树',
'id': 20
}, {
'url': '/index/',
'pid': None,
'title': '首页',
'id': 21
}, {
'url': '/logout/',
'pid': None,
'title': '注销',
'id': 22
}, {
'url': '/customers/add/',
'pid': 1,
'title': '添加客户',
'id': 23
}, {
'url': '/customers/add/',
'pid': 2,
'title': '添加客户',
'id': 24
}, {
'url': '/customers/add/',
'pid': 3,
'title': '添加客户',
'id': 25
}, {
'url': '/customer/del/(\\d+)/',
'pid': 1,
'title': '删除客户',
'id': 26
}, {
'url': '/customer/del/(\\d+)/',
'pid': 2,
'title': '删除客户',
'id': 27
}, {
'url': '/customer/del/(\\d+)/',
'pid': 3,
'title': '删除客户',
'id': 28
}, {
'url': '/customers/edit/(\\d+)',
'pid': 1,
'title': '修改客户',
'id': 29
}, {
'url': '/customers/edit/(\\d+)',
'pid': 2,
'title': '修改客户',
'id': 30
}, {
'url': '/customers/edit/(\\d+)',
'pid': 3,
'title': '修改客户',
'id': 31
}, {
'url': '/consult_records/add/',
'pid': 4,
'title': '添加客户跟进记录',
'id': 32
}, {
'url': '/consult_records/(\\d+)',
'pid': 4,
'title': '修改客户跟进记录',
'id': 33
}, {
'url': '/del_consult/(\\d+)',
'pid': 4,
'title': '删除客户跟进记录',
'id': 34
}]
权限列表
permission_menu_dic {
'': {
'menu_title': '客户管理',
'menu_icon': 'nav-icon fa fa-dashboard',
'childern': [{
'title': '全部客户',
'url': '/customer/'
}, {
'title': '共有客户',
'url': '/customers/list/'
}, {
'title': '我的客户',
'url': '/mycustomers/'
}, {
'title': '客户跟进记录',
'url': '/consult_records/'
}, {
'title': '客户成单统计',
'url': '/customer/count/'
}]
},
'': {
'menu_title': '报名管理',
'menu_icon': 'nav-icon fa fa-table',
'childern': [{
'title': '报名情况',
'url': '/enrollment/'
}]
},
'': {
'menu_title': '成绩管理',
'menu_icon': 'nav-icon fa fa-th',
'childern': [{
'title': '班级学习记录',
'url': '/ClassStudyRecord/list/'
}]
},
'': {
'menu_title': '权限管理',
'menu_icon': 'nav-icon fa fa-tree',
'childern': [{
'title': '角色管理',
'url': '/rbac/role/list/'
}, {
'title': '菜单管理',
'url': '/rbac/menu/list/'
}, {
'title': '分配权限',
'url': '/rbac/permission/distrbute/'
}]
}
}
permission_menu_dic {
'': {
'menu_title': '客户管理',
'menu_icon': 'nav-icon fa fa-dashboard',
'childern': [{
'title': '全部客户',
'url': '/customer/',
'active': 'active'
}, {
'title': '共有客户',
'url': '/customers/list/'
}, {
'title': '我的客户',
'url': '/mycustomers/'
}, {
'title': '客户跟进记录',
'url': '/consult_records/'
}, {
'title': '客户成单统计',
'url': '/customer/count/'
}],
'style': 'display:block',
'class': 'menu-open'
},
'': {
'menu_title': '报名管理',
'menu_icon': 'nav-icon fa fa-table',
'childern': [{
'title': '报名情况',
'url': '/enrollment/'
}]
},
'': {
'menu_title': '成绩管理',
'menu_icon': 'nav-icon fa fa-th',
'childern': [{
'title': '班级学习记录',
'url': '/ClassStudyRecord/list/'
}]
},
'': {
'menu_title': '权限管理',
'menu_icon': 'nav-icon fa fa-tree',
'childern': [{
'title': '角色管理',
'url': '/rbac/role/list/'
}, {
'title': '菜单管理',
'url': '/rbac/menu/list/'
}, {
'title': '分配权限',
'url': '/rbac/permission/distrbute/'
}]
}
}
菜单数据
具体构建代码如下:
from rbac.models import Role def initial_sesson(user,request):
"""
功能:将当前登录人的所有权限录入session中
:param user: 当前登录人
"""
# 查询当前登录人的所有权限列表
# 查看当前登录人的所有角色
# ret=Role.objects.filter(user=user)
permissions = Role.objects.filter(userinfo=user).values("permissions__url",
"permissions__title",
'permissions__pid',
'permissions__pk',
"permissions__menu__pk",
"permissions__menu__title",
"permissions__menu__icon",
).distinct()
print('permissions',permissions) permission_list = []
permission_menu_dic = {} for item in permissions:
# 构建权限列表
permission_list.append({
'url':item["permissions__url"],
'pid':item["permissions__pid"],
'title':item["permissions__title"],
'id':item["permissions__pk"], })
# 构建菜单权限列表
if item["permissions__menu__pk"]:
if not permission_menu_dic.get(item['permissions__menu__pk']): permission_menu_dic[item['permissions__menu__pk']] = {
'menu_title':item['permissions__menu__title'],
'menu_icon':item['permissions__menu__icon'],
'childern':[{
'title':item['permissions__title'],
'url':item['permissions__url']
}]
}
else: permission_menu_dic[item['permissions__menu__pk']]['childern'].append({
'title':item['permissions__title'],
'url':item['permissions__url']
}) print('permission_menu_dic',permission_menu_dic)
# 将当前登录人的权限列表注入session中
request.session["permission_list"] = permission_list
# 将当前登录人的菜单权限列表注入session中
print("permission_list",permission_list)
request.session["permission_menu_dic"] = permission_menu_dic
构建菜单:
这里使用的django的自定义标签incluSion_tags.
首先创建一个templatetags文件夹,(注意这个文件夹的名字必须是这个名字)
其次创建一个py文件,这个文件名可以随意.
代码如下:
from django.utils.safestring import mark_safe
from django.template import Library
import re
register =Library() @register.inclusion_tag("rbac/menu.html")
def get_menu_styles(request):
permission_menu_dic = request.session.get("permission_menu_dic")
print('permission_menu_dic',permission_menu_dic)
for val in permission_menu_dic.values():
for item in val.get('childern'):
if re.search('^{}$'.format(item['url']),request.path):
val['style'] = 'display:block'
val['class'] = 'menu-open'
item['active'] = 'active'
print("permission_menu_dic",permission_menu_dic)
return {"permission_menu_dic":permission_menu_dic}
自定义菜单标签
这里还需要一个菜单的模板:
{% for item in permission_menu_dic.values %}
<li class="nav-item has-treeview {{ item.class }}">
<a href="#" class="nav-link">
<i class="{{ item.menu_icon }}"></i>
<p>
{{ item.menu_title }}
<i class="right fa fa-angle-left"></i>
</p>
</a> <ul class="nav nav-treeview" style="{{ item.style }}">
{% for foo in item.childern %}
<li class="nav-item">
<a href="{{ foo.url }}" class="nav-link {{ foo.active }}">
<i class="fa fa-circle-o nav-icon"></i>
<p>{{ foo.title }}</p>
</a>
</li> {% endfor %}
</ul>
</li>
{% endfor %}
menu
这里的菜单css和js可以自己进行定制.我这里使用的是bootstrap的模板.
自此,菜单以及菜单权限就构建完成!
django 菜单权限的更多相关文章
- Django - 权限(5)- 非菜单权限对应的一级菜单展开、面包屑导航
一.非菜单权限对应的一级菜单展开 需求:客户列表和账单列表页面中都有添加按钮,当点击添加客户(或编辑客户.删除客户)时,客户列表所属的一级菜单展开,当点击添加账单(或编辑账单.删除账单)时,账单列表所 ...
- 巨蟒django之权限8:排序&&菜单展开权限归属
1.权限控制的流程+表结构 内容回顾: wsgi:socket进行收发消息 中间件:(超级重点的面试题)在全局范围内控制django的输入和输出的一个钩子,处理输入和输出说白了就是处理请求和响应req ...
- 巨蟒django之权限7:动态生成一级&&二级菜单
内容回顾: . 权限的控制 . 表结构设计 存权限的信息 用户表 - name 用户名 - pwd 密码 - roles 多对多 角色表 - name - permissions 多对多 权限表 - ...
- django中非菜单权限的归属
非菜单权限的归属 : 1.设置表结构 : 在权限表中添加自连接的外键patent,parent_id连接permission表的id,可为空,当有parent_id时,说明它是一个普通 ...
- Django之权限用法
**记住每一个url都是一个权限** 注册 可插拔试的权限,可以先写其他的逻辑,在最后再把权限加上 将rbac组件拷贝到项目上,注册项目 修改表结构 将写好的用户表对rbac的User表进行一对一的关 ...
- Django万能权限框架组件
业务场景分析 假设我们在开发一个培训机构的 客户关系管理系统,系统分客户管理.学员管理.教学管理3个大模块,每个模块大体功能如下 客户管理 销售人员可以录入客户信息,对客户进行跟踪,为客户办理报名手续 ...
- Lind.DDD.Manager里菜单权限的设计
回到目录 对于一个后台管理系统来说,你的权限设计与安全是重中之重,当你为一个权限分配一些菜单后,当这个权限的用户没有菜单权限时,这个菜单的URL是不可以被用户访问的,而在之前的设计中,没有考虑到这点, ...
- C#winform菜单权限分配,与菜单同步的treeView树状菜单权限控制使用心得
在网上查了很多,发现没有讲述关于--C#winform菜单权限分配,与菜单同步的treeView树状菜单权限控制使用--的资料 自己研究了一个使用方法.下面来看看. 我有两个窗体:LOGINFRM,M ...
- JavaEE权限管理系统的搭建(六)--------使用拦截器实现菜单URL的跳转权限验证和页面的三级菜单权限按钮显示
本小结讲解,点击菜单进行页面跳转,看下图,点击管理员列表后会被认证拦截器首先拦截,验证用户是否登录,如果登录就放行,紧接着会被权限验证拦截器再次拦截,拦截的时候,会根据URL地址上找到对应的方法,然后 ...
随机推荐
- web视频播放插件:Video For Everybody
相比其它的web视频播放插件(video.js , jwplayer等)来说,Video For Everybody(极力推荐)是一款更好的视频播放插件,无需任何下载,支持html5以及flash播放 ...
- (一)U-Boot启动过程--详细版的完全分析
博客地址:http://blog.csdn.net/hare_lee/article/details/6916325
- A - Restaurant
UVA 1468 Description Mr. Kim is planning to open a new restaurant. His city is laid out as a grid ...
- 3.5.6 关系和boolean运算符
Java包含丰富的关系运算符.要检测相等性,可以使用两个等号 == .例如, 3 == 7 的值为 false. 另外可以使用 != 检测不相等.例如, 3 ! = 7 的值 ...
- html to canvas
html to canvas Screenshots https://html2canvas.hertzen.com/ https://github.com/niklasvh/html2canvas ...
- FZU 2109 Mountain Number
http://acm.fzu.edu.cn/problem.php?pid=2109 题意:找出区间[l,r]内满足奇数位的数字大于相邻偶数位数字的个数. 典型的数位dp了,记录一下当前位是奇数位还是 ...
- PHP htmlentities 和 htmlspecialchars的区别
一直对这两个转换htm字符为html实体的函数混淆不清,查询了一下文档,总结如下 htmlentities: Convert all applicable characters to HTML ent ...
- codevs—— 1077 多源最短路
1077 多源最短路 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 已知n个点(n<=100),给你 ...
- Spring/Maven/MyBatis配置文件结合properties文件使用
使用properties文件也叫注入,比如把一些常用的配置项写入到这个文件,然后在Spring的XML配置文件中使用EL表达式去获取. 这种方式不只Spring可以使用,同样MyBatis也可以使用, ...
- Android自己定义提示框
在开发中,假设感觉系统自带的提示框不好看,开发人员能够自定义提示框的样式.主要是继承Dialog 程序文件夹结构 关键代码 package com.dzt.custom.dialog; import ...