一.什么是权限
能做哪些事情,不能做哪些事情,可以做的权限
二.设计权限
思路:
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 { '2': { '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/' }] }, '3': { 'menu_title': '报名管理', 'menu_icon': 'nav-icon fa fa-table', 'childern': [{ 'title': '报名情况', 'url': '/enrollment/' }] }, '4': { 'menu_title': '成绩管理', 'menu_icon': 'nav-icon fa fa-th', 'childern': [{ 'title': '班级学习记录', 'url': '/ClassStudyRecord/list/' }] }, '5': { '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 { '2': { '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' }, '3': { 'menu_title': '报名管理', 'menu_icon': 'nav-icon fa fa-table', 'childern': [{ 'title': '报名情况', 'url': '/enrollment/' }] }, '4': { 'menu_title': '成绩管理', 'menu_icon': 'nav-icon fa fa-th', 'childern': [{ 'title': '班级学习记录', 'url': '/ClassStudyRecord/list/' }] }, '5': { '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 %}
这里的菜单css和js可以自己进行定制.我这里使用的是bootstrap的模板.
自此,菜单以及菜单权限就构建完成!
来源:https://www.cnblogs.com/baijinshuo/p/9963125.html