當Django的內置權限無法滿足需求的時候就自己擴展吧~
背景介紹
overmind項目使用了Django內置的權限系統,Django內置權限系統基于model層做控制,新的model創建后會默認新建三個權限,分別為:add、change、delete,如果給用戶或組賦予delete的權限,那么用戶將可以刪除這個model下的所有數據。
原本overmind只管理了我們自己部門的數據庫,權限設置只針對具體的功能不針對細粒度的數據庫實例,例如用戶A 有審核的權限,那么用戶A 可以審核所有的DB,此時使用內置的權限系統就可以滿足需求了,但隨著系統的不斷完善要接入其他部門的數據庫管理,這就要求針對不同用戶開放不同DB的權限了,例如A部門的用戶只能操作A部門的DB,Django內置基于model的權限無法滿足需求了。
實現過程
先來確定下需求:
1. 保持原本的基于功能的權限控制不變,例如用戶A有查詢權限,B有審核權限
2. 增加針對DB實例的權限控制,例如用戶A只能查詢特定的DB,B只能審核特定的DB
對于上邊需求1用內置的權限系統已經可以實現,這里不贅述,重點看下需求2,DB信息都存放在同一個表里,不同用戶能操作不同的DB,也就是需要把每一條DB信息與有權限操作的用戶進行關聯,為了方便操作,我們考慮把DB跟用戶組關聯,在用戶組里的用戶都有權限,而操作類型經過分析主要有兩類讀和寫,那么需要給每個MySQL實例添加兩個字段分別記錄對此實例有讀和寫權限的用戶組
如下代碼在原來的model基礎上添加 read_groups 和 write_groups 字段,DB實例跟用戶組應是ManyToManyField多對多關系,一個實例可以關聯多個用戶組,一個用戶組也可以屬于多個實例
class Mysql(models.Model): Env = ( (1, 'Dev'), (2, 'Qa'), (3, 'Prod'), ) create_time = models.DateTimeField(auto_now_add=True, verbose_name='創建時間') update_time = models.DateTimeField(auto_now=True, verbose_name='更新時間') project_id = models.IntegerField(verbose_name='項目') project_tmp = models.CharField(max_length=128, default='') environment = models.IntegerField(choices=Env, verbose_name='環境') master_host = models.GenericIPAddressField(verbose_name='master主機') master_port = models.IntegerField(default=3306, verbose_name='master端口') slave_host = models.GenericIPAddressField(null=True, verbose_name='slave主機') slave_port = models.IntegerField(null=True, default=3306, verbose_name='slave端口') database = models.CharField(max_length=64, verbose_name='數據庫') read_groups = models.ManyToManyField(Group, related_name='read', verbose_name='讀權限') write_groups = models.ManyToManyField(Group, related_name='write', verbose_name='寫權限') description = models.TextField(null=True, verbose_name='備注')
新聞熱點
疑難解答