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

1. 什么是 django-guardian

django-guardian 是一款 Django 应用,为您 Django 中的对象提供了对象级别的权限控制。根据官网介绍,django-guardian 可以让您更广泛地使用 Django 权限系统。

django-guardian 给予 Django 的 'User' 和 'Group' 模型的用户权限的概念很大的灵活性。同时,django-guardian 提供针对所有 Django 模型的对象级别的权限。

接下来,我们将介绍 django-guardian 的几个主要特性。

1.1 多重访问控制

django-guardian 拥有许多不同的访问控制机制。您可以基于以下任意层级进行访问控制:

全局 / 应用程序范围内

具体对象(行)

特定字段(列)

1.2 扩展现有模型

django-guardian 可以让您在不更改现有模型的情况下,将对象级别的访问控制添加到它们上面。您不必去扩展和更改每个模型,您可以直接在“Settings”模块中设置权限。 django-guardian 还可以无缝地与 Django 的 Admin 界面配合使用。这意味着您甚至可以为 ModelAdmin 定义自己的权限。

1.3 高度灵活,功能强大

django-guardian 提供了强大的灵活性,可以处理许多不同的权限方案,包括:

需要一个权限才能访问某个对象,即只允许特定的(User或Group)访问。

针对组内成员,而不是组在整体上进行控制,这意味着您可以根据用户的组(而不是单个用户)控制权限。

以可写或只读的方式控制权限。例如,您可以让某个组只能查看某个对象,但不能修改它。

2. django-guardian 如何实现对象级别权限控制

2.1 安装和配置 django-guardian

要安装 django-guardian,请使用 pip 在命令行工具中运行以下命令:

pip install django-guardian

为了使用 django-guardian,您需要将 guardian 添加到您 Django 项目的 INSTALLED_APPS 中:

INSTALLED_APPS = [

...

'guardian',

...

]

此外,您应该添加 guardian.context_processors 应用程序上下文处理器到django 内建 template 的 context_processors 中:

TEMPLATES = [

{

'BACKEND': 'django.template.backends.django.DjangoTemplates',

'APP_DIRS': True,

'OPTIONS': {

'context_processors': [

...

'guardian.context_processors.has_perm',

...

],

},

},

]

2.2 在模板中使用guardian

当您在模板中使用 guardian 时, django-guardian 将扫描当前对象以查找“守护者”,并将它们添加到模板上下文中。

如果您正在处理 Post 对象,并且想要控制哪些用户可以编辑某些 Post 属性,您可以将如下代码添加到你的模板:

# post_detail.html

{% extends "base.html" %}

{% block content %}

{{ post.title }}

{{ post.content }}

{% if perms.post.change_post %}

Edit

{% endif %}

{% endblock content %}

在这个例子中,我们使用 {% if perms.post.change_post %} 来判断当前用户是否有权修改当前的 Post 实例。这行代码定义了一个"change_post"权限。

2.3 使用 API 实现权限控制

您可以使用 Django guardian 的 API 在程序代码中实现对 Django 模型的对象的访问控制。

例如,假设您正在编写一个RESTful API,并且您需要保护用户通过 API 访问的数据。您需要确保只有用户和他们所在组的成员才能查看和修改其数据。

以下是一个示例:

from django.shortcuts import get_object_or_404

from rest_framework import viewsets, permissions

class MyModelViewSet(viewsets.ModelViewSet):

...

permission_classes = [permissions.IsAuthenticated]

def get_queryset(self):

user = self.request.user

if user.is_authenticated:

return Model.objects.filter(user=user)

else:

return Model.objects.none()

def destroy(self, request, *args, **kwargs):

obj = self.get_object()

if request.user.has_perm('myapp.delete_mymodel', obj):

obj.delete()

return Response(status=status.HTTP_204_NO_CONTENT)

else:

return Response(status=status.HTTP_403_FORBIDDEN)

在上面的代码示例中,我们定义了 MyModelViewSet,并使用 django-guardian 的 has_perm() 函数来检查用户是否有权访问该对象。如果用户没有相关权限,则返回 HTTP 4xx 响应。

您可以用类似的方式保护您的 Django 应用程序的其他部分。 django-guardian 的 API 还包括可以细粒度控制对象级别的访问的其他有用函数。

3. django-guardian 对象级别权限控制展示

在 Django 中使用 django-guardian有很多方法,其中一个方法是使用第三方包 django-guardian-cls。该包提供了装饰器,可以在类级别设置对象级别的权限。

以下是一个示例:

from django.contrib.auth.models import User

from django.shortcuts import render

from django.views.generic import DeleteView

from guardian.decorators import permission_required_or_403

from myapp.models import MyModel

class MyModelDeleteView(DeleteView):

template_name = "mymodel_confirm_delete.html"

model = MyModel

@permission_required_or_403('myapp.delete_mymodel', (MyModel, 'pk', 'pk'))

def dispatch(self, *args, **kwargs):

return super(MyModelDeleteView, self).dispatch(*args, **kwargs)

上述代码中,我们将 django-guardian 的 permission_required_or_403 装饰器应用于类的 dispatch 方法。 此装饰器使用 'myapp.delete_mymodel' 权限,并将其应用于 MyModelDeleteView的 delete 方法所应删除的 MyModel实例。

在上面的示例中,只有拥有 'myapp.delete_mymodel' 权限的用户才能访问 MyModelDeleteView,否则将返回 HTTP 403 响应。

总结

通过本文,我们了解了django-guardian的主要特性,django-guardian如何实现对象级别的权限控制以及如何展示。django-guardian具有针对所有Django模型的对象级别的权限,多重访问控制,非常灵活,可以处理许多不同的权限方案。如果您正在处理带有访问控制的Django模型且需要细粒度的访问控制,请考虑使用 django-guardian 实现对您的应用程序的访问控制。

后端开发标签