Django RBAC权限管理设计过程详解


Posted in Python onAugust 06, 2019

一.权限简介

1. 问:为什么程序需要权限控制?

答:生活中的权限限制,① 看灾难片电影《2012》中富人和权贵有权登上诺亚方舟,穷苦老百姓只有等着灾难的来临;② ?潘棵牵?忻挥邢牍??裁茨切┏さ闷?辽聿暮玫墓媚镌谀闵肀卟淮嬖谀兀恳蛭?星?撕推?凉媚锒际钦涔笙∮械模?∮械娜嗽谝黄鹜嫠:徒馑?髦肿耸啤6?悖?奕ㄓ涤兴?牵?荒茏约和孀约毫恕?br />

程序开发时的权限控制,对于不同用户使用系统时候就应该有不同的功能,如:

  • 普通员工
  • 部门主管
  • 总监
  • 总裁

所以,只要有不同角色的人员来使用系统,那么就肯定需要权限系统。

2. 问:为什么要开发权限组件?

答:假设你今年25岁,从今天开始写代码到80岁,每年写5个项目,那么你的一生就会写275个项目,保守估计其中应该有150+个都需要用到权限控制,为了以后不再重复的写代码,所以就开发一个权限组件以便之后55年的岁月中使用。 亲,不要太较真哦,你觉得程序员能到80岁么,哈哈哈哈哈哈哈

偷偷告诉你:老程序员开发速度快,其中一个原因是经验丰富,另外一个就是他自己保留了很多组件,新系统开发时,只需把组件拼凑起来基本就可以完成。

3. 问:web开发中权限指的是什么?

答:web程序是通过 url 的切换来查看不同的页面(功能),所以权限指的其实就是URL,对url控制就是对权限的控制。

结论:一个人有多少个权限就取决于他有多少个URL的访问权限。

二.权限表结构设计:第一版

问答环节中已得出权限就是URL的结论,那么就可以开始设计表结构了。

  • 一个用户可以有多个权限。
  • 一个权限可以分配给多个用户。

你设计的表结构大概会是这个样子:

Django RBAC权限管理设计过程详解

现在,此时此刻是不是觉得自己设计出的表结构棒棒哒!!!

But,无论是是否承认,你还是too young too native,因为老汉腚眼一看就有问题....

问题:假设 “maple”和“ffm” 这俩货都是老板,老板的权限一定是非常多。那么试想,如果给这俩货分配权限时需要在【用户权限关系表中】添加好多条数据。假设再次需要对老板的权限进行修改时,又需要在【用户权限关系表】中找到这俩人所有的数据进行更新,太他妈烦了吧!!! 类似的,如果给其他相同角色的人来分配权限时,必然会非常繁琐。

三.权限表结构设计:第二版

聪明机智的一定在上述的表述中看出了写门道,如果对用户进行角色的划分,然后对角色进行权限的分配,这不就迎刃而解了么。

  • 一个人可以有多个角色。
  • 一个角色可以有多个人。
  • 一个角色可以有多个权限。
  • 一个权限可以分配给多个角色。

表结构设计:

Django RBAC权限管理设计过程详解

这次调整之后,由原来的【基于用户的权限控制】转换成【基于角色的权限控制】,以后再进行分配权限时只需要给指定角色分配一次权限,给众多用户再次分配指定角色即可。

from django.db import models
class Permission(models.Model):
  """
  权限表
  """
  title = models.CharField(verbose_name='标题', max_length=32)
  url = models.CharField(verbose_name='含正则的URL', max_length=128)

  def __str__(self):
    return self.title
class Role(models.Model):
  """
  角色
  """
  title = models.CharField(verbose_name='角色名称', max_length=32)
  permissions = models.ManyToManyField(verbose_name='拥有的所有权限', to='Permission', blank=True)
  def __str__(self):
    return self.title
class UserInfo(models.Model):
  """
  用户表
  """
  name = models.CharField(verbose_name='用户名', max_length=32)
  password = models.CharField(verbose_name='密码', max_length=64)
  email = models.CharField(verbose_name='邮箱', max_length=32)
  roles = models.ManyToManyField(verbose_name='拥有的所有角色', to='Role', blank=True)

  def __str__(self):
    return self.name

注意:现在的设计还不是最终版,但之后的设计都是在此版本基础上扩增的,为了让大家能够更好的理解,我们暂且再此基础上继续开发,直到遇到无法满足的情况,再进行整改。

四.客户管理之动态“一级”菜单

from django.db import models
class Permission(models.Model):
  """
  权限表
  """
  title = models.CharField(verbose_name='标题', max_length=32)
  url = models.CharField(verbose_name='含正则的URL', max_length=128)
  icon = models.CharField(verbose_name='图标', max_length=32, null=True, blank=True, help_text='菜单才设置图标')
  is_menu = models.BooleanField(verbose_name='是否是菜单', default=False)

  def __str__(self):
    return self.title
class Role(models.Model):
  """
  角色
  """
  title = models.CharField(verbose_name='角色名称', max_length=32)
  permissions = models.ManyToManyField(verbose_name='拥有的所有权限', to='Permission', blank=True)

  def __str__(self):
    return self.title
class UserInfo(models.Model):
  """
  用户表
  """
  name = models.CharField(verbose_name='用户名', max_length=32)
  password = models.CharField(verbose_name='密码', max_length=64)
  email = models.CharField(verbose_name='邮箱', max_length=32)
  roles = models.ManyToManyField(verbose_name='拥有的所有角色', to='Role', blank=True)
  def __str__(self):
    return self.name

五.客户管理之动态“二级”菜单

from django.db import models
class Menu(models.Model):
  """
  菜单
  """
  title = models.CharField(verbose_name='菜单', max_length=32)
  icon = models.CharField(verbose_name='图标', max_length=32)
  def __str__(self):
    return self.title
class Permission(models.Model):
  """
  权限表
  """
  title = models.CharField(verbose_name='标题', max_length=32)
  url = models.CharField(verbose_name='含正则的URL', max_length=128)
  menu = models.ForeignKey(verbose_name='菜单', to='Menu', null=True, blank=True, help_text='null表示非菜单')
  def __str__(self):
    return self.title
class Role(models.Model):
  """
  角色
  """
  title = models.CharField(verbose_name='角色名称', max_length=32)
  permissions = models.ManyToManyField(verbose_name='拥有的所有权限', to='Permission', blank=True)
  def __str__(self):
    return self.title
class UserInfo(models.Model):
  """
  用户表
  """
  name = models.CharField(verbose_name='用户名', max_length=32)
  password = models.CharField(verbose_name='密码', max_length=64)
  email = models.CharField(verbose_name='邮箱', max_length=32)
  roles = models.ManyToManyField(verbose_name='拥有的所有角色', to='Role', blank=True)
  def __str__(self):
    return self.name

六.客户管理之默认展开非菜单URL

from django.db import models
class Menu(models.Model):
  """
  菜单
  """
  title = models.CharField(verbose_name='菜单', max_length=32)
  icon = models.CharField(verbose_name='图标', max_length=32)
  def __str__(self):
    return self.title
class Permission(models.Model):
  """
  权限表
  """
  title = models.CharField(verbose_name='标题', max_length=32)
  url = models.CharField(verbose_name='含正则的URL', max_length=128)

  pid = models.ForeignKey(verbose_name='默认选中权限', to='Permission', related_name='ps', null=True, blank=True,
              help_text="对于无法作为菜单的URL,可以为其选择一个可以作为菜单的权限,那么访问时,则默认选中此权限",
              limit_choices_to={'menu__isnull': False})  
  menu = models.ForeignKey(verbose_name='菜单', to='Menu', null=True, blank=True, help_text='null表示非菜单')
  def __str__(self):
    return self.title
class Role(models.Model):
  """
  角色
  """
  title = models.CharField(verbose_name='角色名称', max_length=32)
  permissions = models.ManyToManyField(verbose_name='拥有的所有权限', to='Permission', blank=True)
  def __str__(self):
    return self.title
class UserInfo(models.Model):
  """
  用户表
  """
  name = models.CharField(verbose_name='用户名', max_length=32)
  password = models.CharField(verbose_name='密码', max_length=64)
  email = models.CharField(verbose_name='邮箱', max_length=32)
  roles = models.ManyToManyField(verbose_name='拥有的所有角色', to='Role', blank=True)
  def __str__(self):
    return self.name

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python中使用PyHook监听鼠标和键盘事件实例
Jul 18 Python
python一行sql太长折成多行并且有多个参数的方法
Jul 19 Python
在Python中定义一个常量的方法
Nov 10 Python
Python实现八皇后问题示例代码
Dec 09 Python
python pandas获取csv指定行 列的操作方法
Jul 12 Python
Django对数据库进行添加与更新的例子
Jul 12 Python
Python算法中的时间复杂度问题
Nov 19 Python
Pytorch之parameters的使用
Dec 31 Python
python Shapely使用指南详解
Feb 18 Python
tensorflow模型转ncnn的操作方式
May 25 Python
解决keras backend 越跑越慢问题
Jun 18 Python
Python 爬虫批量爬取网页图片保存到本地的实现代码
Dec 24 Python
python虚拟环境完美部署教程
Aug 06 #Python
python批量图片处理简单示例
Aug 06 #Python
Python实用库 PrettyTable 学习笔记
Aug 06 #Python
浅谈django2.0 ForeignKey参数的变化
Aug 06 #Python
Python中调用其他程序的方式详解
Aug 06 #Python
运用PyTorch动手搭建一个共享单车预测器
Aug 06 #Python
基于python实现自动化办公学习笔记(CSV、word、Excel、PPT)
Aug 06 #Python
You might like
PHP扩展CURL的用法详解
2014/06/20 PHP
wamp安装后自定义配置的方法
2014/08/23 PHP
php通过sort()函数给数组排序的方法
2015/03/18 PHP
PHP简单的MVC框架实现方法
2015/12/01 PHP
php格式文件打开的四种方法
2018/02/24 PHP
JQuery toggle使用分析
2009/11/16 Javascript
数组Array进行原型prototype扩展后带来的for in遍历问题
2010/02/07 Javascript
jquery ajax中使用jsonp的限制解决方法
2013/11/22 Javascript
jquery实现带缩略图的全屏图片画廊效果实例
2015/06/25 Javascript
基于JS实现数字+字母+中文的混合排序方法
2016/06/06 Javascript
jQuery过滤选择器经典应用
2016/08/18 Javascript
Javascript学习之谈谈JS的全局变量跟局部变量(推荐)
2016/08/28 Javascript
Vue.js 父子组件通讯开发实例
2016/09/06 Javascript
jQuery用户头像裁剪插件cropbox.js使用详解
2017/06/07 jQuery
JS实现获取进今年第几天是周几的方法分析
2018/06/27 Javascript
ES6中let 和 const 的新特性
2018/09/03 Javascript
Python压缩解压缩zip文件及破解zip文件密码的方法
2015/11/04 Python
Python常见格式化字符串方法小结【百分号与format方法】
2016/09/18 Python
python脚本实现验证码识别
2018/06/07 Python
用Python将一个列表分割成小列表的实例讲解
2018/07/02 Python
详细介绍Python进度条tqdm的使用
2019/07/31 Python
Python爬虫库BeautifulSoup获取对象(标签)名,属性,内容,注释
2020/01/25 Python
python requests.get带header
2020/05/05 Python
大学生新闻专业个人自我评价
2013/11/12 职场文书
营销专业应届生求职信
2013/11/26 职场文书
社区端午节活动方案
2014/01/28 职场文书
学生安全教育材料
2014/02/14 职场文书
经典演讲稿汇总
2014/05/19 职场文书
全国优秀教师事迹材料
2014/08/26 职场文书
医药公司采购员岗位职责
2014/09/12 职场文书
营销总监岗位职责
2014/09/16 职场文书
农村党支部书记四风问题个人对照检查材料
2014/09/21 职场文书
销售工作决心书
2015/02/04 职场文书
行政申诉状范文
2015/05/20 职场文书
小学运动会入场口号
2015/12/24 职场文书
HTML中实现音乐或视频自动播放案例详解
2022/05/30 HTML / CSS