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 %}
{% 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 实现对您的应用程序的访问控制。