Django RBAC權(quán)限管理設(shè)計過程詳解
一.權(quán)限簡介
1. 問:為什么程序需要權(quán)限控制?
答:生活中的權(quán)限限制,① 看災(zāi)難片電影《2012》中富人和權(quán)貴有權(quán)登上諾亞方舟,窮苦老百姓只有等著災(zāi)難的來臨;② 屌絲們,有沒有想過為什么那些長得漂亮身材好的姑娘在你身邊不存在呢?因為有錢人和漂亮姑娘都是珍貴稀有的,稀有的人在一起玩耍和解鎖各種姿勢。而你,無權(quán)擁有他們,只能自己玩自己了。
程序開發(fā)時的權(quán)限控制,對于不同用戶使用系統(tǒng)時候就應(yīng)該有不同的功能,如:
- 普通員工
- 部門主管
- 總監(jiān)
- 總裁
所以,只要有不同角色的人員來使用系統(tǒng),那么就肯定需要權(quán)限系統(tǒng)。
2. 問:為什么要開發(fā)權(quán)限組件?
答:假設(shè)你今年25歲,從今天開始寫代碼到80歲,每年寫5個項目,那么你的一生就會寫275個項目,保守估計其中應(yīng)該有150+個都需要用到權(quán)限控制,為了以后不再重復(fù)的寫代碼,所以就開發(fā)一個權(quán)限組件以便之后55年的歲月中使用。 親,不要太較真哦,你覺得程序員能到80歲么,哈哈哈哈哈哈哈
偷偷告訴你:老程序員開發(fā)速度快,其中一個原因是經(jīng)驗豐富,另外一個就是他自己保留了很多組件,新系統(tǒng)開發(fā)時,只需把組件拼湊起來基本就可以完成。
3. 問:web開發(fā)中權(quán)限指的是什么?
答:web程序是通過 url 的切換來查看不同的頁面(功能),所以權(quán)限指的其實就是URL,對url控制就是對權(quán)限的控制。
結(jié)論:一個人有多少個權(quán)限就取決于他有多少個URL的訪問權(quán)限。
二.權(quán)限表結(jié)構(gòu)設(shè)計:第一版
問答環(huán)節(jié)中已得出權(quán)限就是URL的結(jié)論,那么就可以開始設(shè)計表結(jié)構(gòu)了。
- 一個用戶可以有多個權(quán)限。
- 一個權(quán)限可以分配給多個用戶。
你設(shè)計的表結(jié)構(gòu)大概會是這個樣子:

現(xiàn)在,此時此刻是不是覺得自己設(shè)計出的表結(jié)構(gòu)棒棒噠!??!
But,無論是是否承認(rèn),你還是too young too native,因為老漢腚眼一看就有問題....
問題:假設(shè) “maple”和“ffm” 這倆貨都是老板,老板的權(quán)限一定是非常多。那么試想,如果給這倆貨分配權(quán)限時需要在【用戶權(quán)限關(guān)系表中】添加好多條數(shù)據(jù)。假設(shè)再次需要對老板的權(quán)限進(jìn)行修改時,又需要在【用戶權(quán)限關(guān)系表】中找到這倆人所有的數(shù)據(jù)進(jìn)行更新,太他媽煩了吧?。。?類似的,如果給其他相同角色的人來分配權(quán)限時,必然會非常繁瑣。
三.權(quán)限表結(jié)構(gòu)設(shè)計:第二版
聰明機智的一定在上述的表述中看出了寫門道,如果對用戶進(jìn)行角色的劃分,然后對角色進(jìn)行權(quán)限的分配,這不就迎刃而解了么。
- 一個人可以有多個角色。
- 一個角色可以有多個人。
- 一個角色可以有多個權(quán)限。
- 一個權(quán)限可以分配給多個角色。
表結(jié)構(gòu)設(shè)計:

這次調(diào)整之后,由原來的【基于用戶的權(quán)限控制】轉(zhuǎn)換成【基于角色的權(quán)限控制】,以后再進(jìn)行分配權(quán)限時只需要給指定角色分配一次權(quán)限,給眾多用戶再次分配指定角色即可。
from django.db import models
class Permission(models.Model):
"""
權(quán)限表
"""
title = models.CharField(verbose_name='標(biāo)題', 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='擁有的所有權(quán)限', 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
注意:現(xiàn)在的設(shè)計還不是最終版,但之后的設(shè)計都是在此版本基礎(chǔ)上擴(kuò)增的,為了讓大家能夠更好的理解,我們暫且再此基礎(chǔ)上繼續(xù)開發(fā),直到遇到無法滿足的情況,再進(jìn)行整改。
四.客戶管理之動態(tài)“一級”菜單
from django.db import models
class Permission(models.Model):
"""
權(quán)限表
"""
title = models.CharField(verbose_name='標(biāo)題', max_length=32)
url = models.CharField(verbose_name='含正則的URL', max_length=128)
icon = models.CharField(verbose_name='圖標(biāo)', max_length=32, null=True, blank=True, help_text='菜單才設(shè)置圖標(biāo)')
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='擁有的所有權(quán)限', 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
五.客戶管理之動態(tài)“二級”菜單
from django.db import models
class Menu(models.Model):
"""
菜單
"""
title = models.CharField(verbose_name='菜單', max_length=32)
icon = models.CharField(verbose_name='圖標(biāo)', max_length=32)
def __str__(self):
return self.title
class Permission(models.Model):
"""
權(quán)限表
"""
title = models.CharField(verbose_name='標(biāo)題', 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='擁有的所有權(quán)限', 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
六.客戶管理之默認(rèn)展開非菜單URL
from django.db import models
class Menu(models.Model):
"""
菜單
"""
title = models.CharField(verbose_name='菜單', max_length=32)
icon = models.CharField(verbose_name='圖標(biāo)', max_length=32)
def __str__(self):
return self.title
class Permission(models.Model):
"""
權(quán)限表
"""
title = models.CharField(verbose_name='標(biāo)題', max_length=32)
url = models.CharField(verbose_name='含正則的URL', max_length=128)
pid = models.ForeignKey(verbose_name='默認(rèn)選中權(quán)限', to='Permission', related_name='ps', null=True, blank=True,
help_text="對于無法作為菜單的URL,可以為其選擇一個可以作為菜單的權(quán)限,那么訪問時,則默認(rèn)選中此權(quán)限",
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='擁有的所有權(quán)限', 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
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
django框架之cookie/session的使用示例(小結(jié))
這篇文章主要介紹了django框架之cookie/session的使用示例(小結(jié)),詳細(xì)的介紹了cookie和session技術(shù)的接口獲取等問題,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-10-10
python實現(xiàn)愛奇藝登陸密碼RSA加密的方法示例詳解
這篇文章主要介紹了python實現(xiàn)愛奇藝登陸的密碼RSA加密的方法,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-05-05
Django websocket原理及功能實現(xiàn)代碼
這篇文章主要介紹了Django websocket原理及功能實現(xiàn)代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-11-11
Python3使用Selenium獲取session和token方法詳解
這篇文章主要介紹了Python3使用Selenium獲取session和token方法詳解,需要的朋友可以參考下2021-02-02
100行Python代碼實現(xiàn)每天不同時間段定時給女友發(fā)消息
這篇文章主要介紹了100行Python代碼,每天不同時間段定時給女友發(fā)消息,本文給出了實現(xiàn)思路,代碼簡單易懂非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2019-09-09
Python深度學(xué)習(xí)實戰(zhàn)PyQt5窗口切換的堆疊布局示例詳解
本文以堆疊窗口控件為例,詳細(xì)介紹堆疊布局的界面設(shè)計和程序?qū)崿F(xiàn)過程,通過案例帶小白創(chuàng)建一個典型的堆疊布局多窗口切換程序2021-10-10

