安装
# pip install django-guardian配置
settings.py 中注册 django-guardian
INSTALLED_APPS = ( # ... 'guardian', )settings.py 中添加配置用于 django-guardian 身份权限验证
AUTHENTICATION_BACKENDS = ( 'django.contrib.auth.backends.ModelBackend', # this is default 'guardian.backends.ObjectPermissionBackend', )把 django-guardian 整合到 django-admin 中
这里以 autoops 项目的 container 应用中的 KubernetesManager 类为例说明!即 app 为 container、 model 为 KubernetesManager
在 container app 中的 admin.py 文件中,将需要用到行级权限的 model 由原来继承 admin.ModelAdmin 改成 GuardedModelAdmin
from django.contrib import admin from guardian.admin import GuardedModelAdmin from .models import KubernetesManager # Register your models here. class KubernetesManagerAdmin(GuardedModelAdmin): pass admin.site.register(KubernetesManager, KubernetesManagerAdmin)配置保存上述配置后,在 django 后台页面中选择 KubernetesManager 这个 model 选择其中一行数据打开后,在页面右上角“历史”按钮旁边会增加“对象权限”按钮,点击该按钮即可对该行的数据进行具体的权限授权,可以授权给用户、组等, 这里我授权其中一行数据给我的测试用户 test1
使用 get_objects_for_user 方法获取用户对应权限的数据
我这里使用 get_objects_for_user 是获取当前用户 request.user 对 kubernetesmanager 表里有对应的 container.view_kubernetesmanager 权限的数据,也就是有查看权限的数据 所以在 container app 中的 views.py 文件中,我就会用如下代码用于获取当前登录用户的具体 container.view_kubernetesmanager 权限的数据
results = get_objects_for_user(request.user, "container.view_kubernetesmanager")比如请求这个 views 所对应在 url 的用户为 admin 用户,则 results 结果为 kubernetesmanager 中的所有行数据(当前测试表中一共两条数据)
<QuerySet [<KubernetesManager: 本地测试环境>, <KubernetesManager: 另一个测试环境>]>我用 test1 在 admin 后台中只授予其中一行数据,即在“对象权限”中授权了其中的一行数据给 test1 用户为 view_kubernetesmanager 权限,请求这个 views 所对应的 url 用户为 test1 时,results 结果如下
<QuerySet [<KubernetesManager: 本地测试环境>]>然后根据上述不同的 queryset 结果然后处理返回给前端页面展示即可。这就实现了对不同用户控制其指定对象的权限,也就是数据库表里的行权限,我这里其实用途就是实现不用用户可以读取到不同的 K8s 管理配置从而管理不同的 K8s 环境。
这里再贴上 django-guardian 官网上的例子:
from django.shortcuts import render from django.template import RequestContext from projects.models import Project from guardian.shortcuts import get_objects_for_user def user_dashboard(request, template_name='projects/dashboard.html'): projects = get_objects_for_user(request.user, 'projects.view_project') return render(request, template_name, {'projects': projects}, RequestContext(request))更多权限实例可以参考 django-guardian 官网