一、目录结构

二、表结构设计

model.py

from django.db import models

# Create your models here.

class Menu(models.Model):
"""菜单表 一级菜单"""
title = models.CharField(max_length=32)
icon = models.CharField(max_length=64, null=True, blank=True, verbose_name='图标') def __str__(self):
return self.title class Permission(models.Model):
"""
权限表
可以做二级菜单的权限 menu 关联 菜单表
不可以做菜单的权限 menu=null
"""
url = models.CharField(max_length=32, verbose_name='权限')
title = models.CharField(max_length=32, verbose_name='标题')
menu = models.ForeignKey("Menu",null=True, blank=True, verbose_name="所属菜单",on_delete=models.CASCADE) class Meta:
# 这个选项是指定,模型的复数形式是什么,比如:
# verbose_name_plural = "学校"
# 如果不指定Django会自动在模型名称后加一个’s’
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('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('Role', verbose_name='用户拥有的角色',blank=True) def __str__(self):
return self.name

三、权限信息初始化

用户登陆成功后保留权限信息与菜单信息

service.permission.py

from django.conf import settings

def init_permisson(request, obj):
"""
权限信息的初识化
保存权限和菜单的信息
:param request:
:param obj:
:return:
"""
# 登陆成功,保存权限的信息(可能存在创建了角色没有分配权限,有的用户拥有多个角色权限重复的要去重.distinct())
ret = obj.roles.all().filter(permissions__url__isnull=False).values('permissions__url',
'permissions__title',
'permissions__menu__title',
'permissions__menu__icon',
'permissions__menu_id'
).distinct() # 存放权限信息
permission_list = []
# 存放菜单信息
menu_dict = {}
for item in ret:
# 将所有的权限信息添加到permission_list
permission_list.append({'url': item['permissions__url']}) # 构造菜单的数据结构
menu_id = item.get('permissions__menu_id') # 表示当前的权限是不做菜单的权限
if not menu_id:
continue # 可以做菜单的权限
if menu_id not in menu_dict:
menu_dict[menu_id] = {
'title': item['permissions__title'], # 一级菜单标题
'icon': item['permissions__menu__icon'],
'children': [
{'title': item['permissions__menu__title'], 'url': item['permissions__url']},
]
}
else:
menu_dict[menu_id]['children'].append(
{'title': item['permissions__menu__title'], 'url': item['permissions__url']}) # print(menu_dict)
# 保留权限信息到session(因为session可以存到内存中,提高工作效率)中
request.session[settings.PERMISSION_SESSION_KEY] = permission_list # 保存菜单信息
request.session[settings.PERMISSION_MENU_KEY] = menu_dict

四、中间件中权限校验

菜单数据结构构造

注意构造菜单的数据结构,将查询出的元数据构造为分级的数据结构。

# 元数据
data = [{
'permissions__url': '/customer/list/',
'permissions__title': '客户列表',
'permissions__menu__title': '信息列表',
'permissions__menu__icon': 'fa-code-fork',
'permissions__menu_id': 1
},
{
'permissions__url': '/customer/list/',
'permissions__title': '用户列表',
'permissions__menu__title': '信息列表',
'permissions__menu__icon': 'fa-code-fork',
'permissions__menu_id': 1
}, {
'permissions__url': '/customer/add/',
'permissions__title': '增加客户',
'permissions__menu__title': None,
'permissions__menu__icon': None,
'permissions__menu_id': None
}, {
'permissions__url': '/customer/edit/(\\d+)/',
'permissions__title': '编辑客户',
'permissions__menu__title': None,
'permissions__menu__icon': None,
'permissions__menu_id': None
}]
# 目标数据
{
1:{
'title':'信息列表',
'icon':'fa-code-fork',
'children': [
{'title': '客户列表','url':'/customer/list/ },
{'title': '用户列表','url':'/customer/list/ }
] } }

middlewares.rbac.py

from django.conf import settings

def init_permisson(request, obj):
"""
权限信息的初识化
保存权限和菜单的信息
:param request:
:param obj:
:return:
"""
# 登陆成功,保存权限的信息(可能存在创建了角色没有分配权限,有的用户拥有多个角色权限重复的要去重.distinct())
ret = obj.roles.all().filter(permissions__url__isnull=False).values('permissions__url',
'permissions__title',
'permissions__menu__title',
'permissions__menu__icon',
'permissions__menu_id'
).distinct() # 存放权限信息
permission_list = []
# 存放菜单信息
menu_dict = {}
for item in ret:
# 将所有的权限信息添加到permission_list
permission_list.append({'url': item['permissions__url']}) # 构造菜单的数据结构
menu_id = item.get('permissions__menu_id') # 表示当前的权限是不做菜单的权限
if not menu_id:
continue # 可以做菜单的权限
if menu_id not in menu_dict:
menu_dict[menu_id] = {
'title': item['permissions__title'], # 一级菜单标题
'icon': item['permissions__menu__icon'],
'children': [
{'title': item['permissions__menu__title'], 'url': item['permissions__url']},
]
}
else:
menu_dict[menu_id]['children'].append(
{'title': item['permissions__menu__title'], 'url': item['permissions__url']}) # print(menu_dict)
# 保留权限信息到session(因为session可以存到内存中,提高工作效率)中
request.session[settings.PERMISSION_SESSION_KEY] = permission_list # 保存菜单信息
request.session[settings.PERMISSION_MENU_KEY] = menu_dict

五、自定义inclusion_tag

用于定义html片段,实现动态数据传入。

文件包必须叫templatetags

templatetags.rbac.py

from django import template
from django.conf import settings
import re register = template.Library() @register.inclusion_tag('rbac/menu.html')
def menu(request):
# # 取到存在session 里的菜单权限信息信息(一级菜单时)
# menu_list = request.session.get(settings.PERMISSION_MENU_KEY)
#
# for item in menu_list:
# # 正则匹配当前路径
# if re.match('^{}$'.format(item['url']), request.path_info):
# # 添加一个点击样式
# item['class'] = 'active'
# break
# return {"menu_list": menu_list} # 二级菜单时
menu_dict = request.session.get(settings.PERMISSION_MENU_KEY) return {'menu_list': menu_dict.values()}

注意:为了不把数据写死,便于维护,存在session中的权限相关配置写在setting中

# session中保留权限key
PERMISSION_SESSION_KEY = 'permissions'
# 保留菜单信息key
PERMISSION_MENU_KEY = 'menus'
# 白名单
WHITE_LIST = [
r'^/login/$',
r'^/reg/$',
r'^/admin/.*',
]

在templates模板中应用菜单

html

   {% load rbac %}
{# <!--应用inclusion_tag('rbac/menu.html')-->#}
{% menu request %}

django自定义rbac权限组件(二级菜单)的更多相关文章

  1. django权限之二级菜单

    遗漏知识点 1.构建表结构时,谁被关联谁就是主表,在层级删除的时候,删除子表的时候,主表不会被删除,反之删除主表的话,字表也会被删除, 使用related_name=None   反向查询,起名用的 ...

  2. rbac权限组件整合到实际项目的全过程详述

    rbac简介 项目的GitHub地址 欢迎Download&Fork&Star:https://github.com/Wanghongw/CombineRbac 另外,本文只简单介绍一 ...

  3. CRM项目之RBAC权限组件-day26

    写在前面 上课第26天,打卡: 世间安得双全法 不负如来不负卿 s17day26 CRM项目 项目概要:XX公司CRM - 权限管理,公共组件,app ***** - 熟悉增删改查,Low *** - ...

  4. RABC权限控制(二级菜单实现)

    目前大部分系统由于用户体验,基本上菜单不会做的很深,以二级菜单为例,做了一个简单的权限控制实现,可精确到按钮级别(基于django),下面具体看看实现 1.表结构的设计 无论开发什么都需要先梳理清楚需 ...

  5. yii2 rbac权限控制之菜单menu详细教程

    作者:白狼 出处:http://www.manks.top/article/yii2_rbac_menu本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则 ...

  6. 1、rbac权限组件-初识, 中间件校验1

    1.权限组件rbac 1.什么是权限 1 项目与应用 2 什么是权限? 一个包含正则表达式url就是一个权限 who what how ---------->True or Flase 2.版本 ...

  7. django中的构造字典(二级菜单,评论树,购物车)

    1.构造父子结构: 1.1需求样式 客户列表 customer_list /customer/list/ -----> 添加客户 customer_add /customer/add/ ---- ...

  8. Django REST framework —— 权限组件源码分析

    在上一篇文章中我们已经分析了认证组件源码,我们再来看看权限组件的源码,权限组件相对容易,因为只需要返回True 和False即可 代码 class ShoppingCarView(ViewSetMix ...

  9. Django实现Rbac权限管理

    权限管理 权限管理是根据不同的用户有相应的权限功能,通常用到的权限管理理念Rbac. Rbac 基于角色的权限访问控制(Role-Based Access Control)作为传统访问控制(自主访问, ...

随机推荐

  1. Oracle11gr2_ADG管理之跳归档恢复dg实战

    模拟故障 关闭备库 SQL> shutdown immediate; Database closed. Database dismounted. ORACLE instance shut dow ...

  2. ocx控件针对网页刷新和关闭分别进行区分处理

    当ocx加载在网页上时,如果对网页执行F5刷新事件,ocx控件会销毁ocx的窗口类,但是ocx的APP类是不会销毁的. 只有当网页被关闭时,才销毁app类. --------------------- ...

  3. webpack4+vue2+axios+vue-router的多页+单页混合应用框架

    VUE2的单页应用框架有人分享了,多页应用框架也有人分享了,这里就分享一个单页和多页的混合应用框架吧,初现雏形,还有很多需要优化和改善的地方... 结尾有github地址. 项目结构 │ ├─buil ...

  4. 通过键盘上下键 JS事件,控制候选词的选择项

    效果图 JS代码 //上下键 选择事件 searchBackgroud 为样式,只做标记,无实质样式,因为和其他样式不兼容,只能添加CSS $(document).keydown(function ( ...

  5. OpenGL顶点缓冲区对象

    [OpenGL顶点缓冲区对象] 显示列表可以快速简单地优化立即模式(glBegin/glEnd)的代码.在最坏的情况下,显示列表的命令被预编译存到命令缓冲区中,然后发送给图形硬件.在最好的情况下,是编 ...

  6. Android4.0+锁屏程序开发——设置锁屏页面篇

    [如何开发一个锁屏应用] 想要开发一个锁屏应用,似乎很难,其实并没有想象中那么难. 从本质上来说,锁屏界面也只是一个Activity而已,只是这个界面比较特殊,在我们点亮屏幕的时候,这个界面就会出现. ...

  7. linux SIGSEGV 信号捕捉,保证发生段错误后程序不崩溃

    在Linux中编程的时候 有时候 try catch 可能满足不了我们的需求.因为碰到类似数组越界 ,非法内存访问之类的 ,这样的错误无法捕获.下面我们介绍一种使用捕获信号实现的异常 用来保证诸如段错 ...

  8. 【转】LVS负载均衡之session解决方案 持久连接

    原文地址:http://minux.blog.51cto.com/8994862/1744761 1. 持久连接是什么? 1.1 在LVS中,持久连接是为了用来保证当来自同一个用户的请求时能够定位到同 ...

  9. 项目二:品优购 第二天 AngularJS使用 brand商品页面的增删改查

    品优购电商系统开发 第2章 品牌管理 传智播客.黑马程序员 1.前端框架AngularJS入门 1.1 AngularJS简介 AngularJS  诞生于2009年,由Misko Hevery 等人 ...

  10. WEB测试和APP测试区别

    Web测试和App测试从流程上来说,没有区别.都需要经历测试计划方案,用例设计,测试执行,缺陷管理,测试报告等相关活动.从技术上来说,WEB测试和APP测试其测试类型也基本相似,都需要进行功能测试.性 ...