django - 如何在基于函数的视图 Django 中分别添加对 GET、POST、PATCH、DELETE 的自定义权限
问题描述
我正在开发一个项目,该项目具有多种用户类型,例如管理员、协调员、副协调员,每个用户都可以在不同的部门担任不同的角色。例如。用户 A 可以是 XX 部门的协调员,然后 A 可以是 YY 部门的管理员,但他不能在同一部门担任相同的角色。
我打算为此编写自定义权限和角色。我写的是这样的:
def coordinator(request, uid):
if request.method == 'GET':
//some logic
if request.method == 'POST':
//some logic
if request.method == 'PATCH':
//some logic
if request.method == 'DELETE':
//some logic
我不想做的是以下方法:
def coordiantor_delete(request, uid):
if request.method == 'DELETE':
def coordiantor_detail(request, uid):
if request.method == 'GET':
def coordiantor_create(request):
if request.method == 'POST':
def coordiantor_update(request, uid):
if request.method == 'PATCH':
有没有一种方法可以为视图函数的特定 HTTP 方法添加权限,而无需将其拆分为各种视图。因为我只想拥有一个像 /coordinator/ 和 /coordinator/id/ 这样的 API 端点,它们应该支持上述 HTTP 方法,但具有像 admin 这样的权限也可以从部门中删除协调员,而协调员自己也可以离开部门而没有其他人对 DELETE 方法具有此权限。让我知道对此有哪些可能的方法或需要进行的其他一些更改。
解决方案
我已经编辑了我的答案,以尝试更好地满足您的需求。这不是一个完整的解决方案,我会考虑对其进行重构并根据您的需要对其进行定制。
我想到了两个解决方案,
- 创建一个装饰器,接受一个函数来检查某些方法的限制,并引发调用 403 模板的 PermissionDenied。
- 创建一个简单的函数来进行一些测试,如果测试失败,则引发 PermissionDenied。在视图函数的每个方法中调用此函数。
由于装饰器的可重用性,我更喜欢方法 1。
这是我的初始设置
from functools import wraps
from django.core.exceptions import PermissionDenied
from django.http import HttpResponse
def permission_denied_test(test_func):
"""
Decorator for views that raises PermissionDenied if test_func fails
The test should be a callable and returns True if the test is passed
Your test function has access to the views request object
"""
def decorator(view_func):
@wraps(view_func)
def _wrapped_view(request, *args, **kwargs):
if test_func(request):
return view_func(request, *args, **kwargs)
raise PermissionDenied
return _wrapped_view
return decorator
def coordinator_passes_test(request):
if request.method == 'GET':
return True # passed test
elif request.method == 'POST':
return False # failed test
@permission_denied_test(coordinator_passes_test)
def view(request):
if request.method == 'GET':
return HttpResponse('Passed test, this code is reached.')
elif request.method == 'POST':
return HttpResponse('Failed test, this code isnt reached.')
这样你的测试是可重用的,你可以轻松地将它应用到多个视图
推荐阅读
- flutter - 使用带有 Flutter 的 Android Studio 模拟器时出现问题
- google-apps-script - DriveApp 不喜欢新文件夹?
- python - 如何在没有 --update-alternatives 的情况下设置默认 Python 版本
- python - 使用 numpy 矩阵运算优化矩阵分解算法
- api - 使用两个数据源对响应进行分页
- python - 从数据帧构建网络图的有效和更快的方法?
- javascript - 从 MYSQL 检索图像并在 HTML 中显示
- javascript - 将两个 javascript 视觉效果添加到 html 页面
- javascript - 关于从 Slice 到 index.js 的响应数据的问题 - React redux 工具包
- swift - 需要帮助将 carthage 依赖项添加到我正在创作的 React Native 包中