Django内置权限扩展案例

当Django的内置权限无法满足需求的时候就自己扩展吧~

背景介绍

overmind项目使用了Django内置的权限系统,Django内置权限系统基于model层做控制,新的model创建后会默认新建三个权限,分别为:add、change、delete,如果给用户或组赋予delete的权限,那么用户将可以删除这个model下的所有数据。

原本overmind只管理了我们自己部门的数据库,权限设置只针对具体的功能不针对细粒度的数据库实例,例如用户A 有审核的权限,那么用户A 可以审核所有的DB,此时使用内置的权限系统就可以满足需求了,但随着系统的不断完善要接入其他部门的数据库管理,这就要求针对不同用户开放不同DB的权限了,例如A部门的用户只能操作A部门的DB,Django内置基于model的权限无法满足需求了。

实现过程

先来确定下需求:

保持原本的基于功能的权限控制不变,例如用户A有查询权限,B有审核权限

增加针对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='备注')

model确定了,接下来我们分三部分详细介绍下权限验证的具体实现

列表页权限控制

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wspjzx.html