使用django-guardian实现django-admin的行级权限控制的方法

  

用django框架来做一些后台管理的web页面简直太方便了,django自带模块级的权限系统,用来做一些内部的系统非常合适,可以大大的减少开发量。但是django自带的权限系统还不支持行级的权限控制,如果要实现行级的权限控制,需要依赖第三方的应用程序来开发,或者自己重新写一个。

  

<强>需求描述
  

  

我们项目组开发的一些系统通常会用mysql数据库来存储一些配置,但是如果每次有配置修改的时候都去手动修改mysql数据的话,会挺麻烦的,同时也比较容易出错.django-admin能够根据定义的模型自动的生成相应的页面,同时还能提供权限的管理,所以我们就把一些系统到的配置放到django中。但是到现在,随着系统的需求越来越多,该系统已经不止我们自己项目组的人员使用,也要开放给其他项目组的同事使用,所以就产生了一些更细粒度的权限需求,因此,我们要在现有的系统上支持行级的权限控制。

  

<>强解决方案
  

  

当然可以自己写一套权限系统了,但是自己写的成本比较高,而且自己写的不一定比较好,所以我就先在网上找了一些现成的解决方案,https://djangopackages.org/grids/g/perms/该链接列出了现有的一些第三方的权限系统解决方案。从该页面来看,django-guardian是最受欢迎的第三方权限系统,而且支持行级的权限系统,同时还可以整合到django-admin里面,所以我就选择了django-guardian。

  

<>强关键步骤
  

  

<>强安装配置django-guardian
  

  

安装配置django-guardian比较简单,按照她项目提供的文档进行安装就可以了,安装完成后会在数据库里面创建两张权限相关的表。

  

<强>把django-guardian整合到django-admin
  

  

首先把admin.py文件里面需要用到行级权限的类,由原来的继承admin.ModelAdmin,改成继承GuardedModelAdmin,这时候打开某个数据行的页面的时候,在该页面的右上角的历史旁边会显示编辑对象权限的按钮,点击该按钮进去相应的页面就可以编辑该行数据的具体权限。

  

配置完权限的时候,用一个新的用户测试的话,会发现该用户没有权限来访问任何的数据,这是因为GuardedModelAdmin还有很多事情没有帮我们做,我们还需要重写一些函数来实现管理后台页面的显示。具体的信息看下面的代码注释。

        来自《卫报》。管理导入GuardedModelAdmin   来自《卫报》。快捷方式进口get_objects_for_user assign_perm、remove_perm get_users_with_perms \   get_groups_with_perms      #需改前   @admin.register (DataAssistantJob)   类DataAssistantJobAdmin (admin.ModelAdmin):   通过      #修改后   @admin.register (DataAssistantJob)   类DataAssistantJobAdmin (GuardedModelAdmin):   #应用是否在主页面中显示的话由该函数决定   def has_module_permission(自我,要求):   如果超级().has_module_permission(请求):   还真   返回self.get_model_objs(请求).exists ()      #在显示数据列表额时候,哪些数据显示,哪些不显示,由该函数控制   def get_queryset(自我,要求):   如果request.user.is_superuser:   返回super () .get_queryset(请求)      data=https://www.yisu.com/zixun/self.get_model_objs(请求)   返回数据      #内部用来获取某个用户有权限访问的数据行   def get_model_objs(自我要求,action=None, klass=None):   选择=self.opts   行动=[行动]如果其他行动(“视图”,“改变”,“删除”)   如果其他klass opts.model klass=klass   model_name=klass._meta.model_name   返回get_objects_for_user(用户=请求。用户,烫发=[f '{烫}_ {model_name}’烫的行动),   klass=klass any_perm=True)      #用来判断某个用户是否有某个数据行的权限   def has_perm(自我、请求、obj行动):   选择=self.opts   代号=f '{行动}_ {opts.model_name} '   如果obj:   返回request.user.has_perm (f ' {opts.app_label}。{代号}’,obj)   其他:   回归自我。get_model_objs(请求、动作).exists ()      #是否有查看某个数据行的权限   def has_view_permission(自我,请求,obj=None):   回归自我。has_perm(请求、obj‘视图’)      #是否有修改某个数据行的权限   def has_change_permission(自我,请求,obj=None):   回归自我。has_perm(请求、obj“变化”)      #是否有删除某个数据行的权限   def has_delete_permission(自我,请求,obj=None):   回归自我。has_perm(请求、obj‘删除’)      #用户应该拥有他新增的数据行的所有权限   def save_model(自我、请求、obj形式,改变):   结果=超级()。save_model(请求、obj形式,改变)   如果不是request.user。is_superuser并没有改变:   选择=self.opts   行动=(“视图”,“添加”,“改变”,“删除”)   [assign_perm (f ' {opts.app_label},{行动}_{选择。model_name}”,请求。用户、obj)对行动的行为)   返回结果      

使用django-guardian实现django-admin的行级权限控制的方法