Django 利用 django-guardian 实现对象级别权限控制以及展示

时间:2022-12-08 14:01:57

安装

# 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 官网