python - 将变量传递给 DRF 中的权限类会出错
问题描述
我正在尝试在项目的许多应用程序中使用以下权限类,唯一需要更改的是从中检查用户数据的模型类。
权限类:
class IsAuthorOrForbidden(permissions.BasePermission):
"""
Check if the requesting user the author or not
"""
def __init__(self, modelClass):
self.modelClass = modelClass
def has_permission(self, request, view):
# get the needed model instance or 404 if not available
instance = get_object_or_404(self.modelClass, pk=view.kwargs['pk'])
# Check if the requesting user is the author
if instance.user == request.user:
return True
return False
视图类中的权限类:
class TextNoteGenerateShareKeyAPIView(generics.UpdateAPIView):
"""
Generate a new text note share key
"""
authentication_classes = (TokenAuthentication,)
permission_classes = (IsAuthenticated,
IsAuthorOrForbidden(modelClass=TextNote))
...
当我运行测试时,我收到此错误:
return [permission() for permission in self.permission_classes] TypeError: 'IsAuthorOrForbidden' object is not callable
是否可以这样做,或者我应该在项目中的每个应用程序中编写这个权限类?
解决方案
您可以使用对象级权限:
class IsAuthorOrForbidden(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
return obj.user == request.user
并将其添加到视图中,如下所示:
permission_classes = (IsAuthenticated,
IsAuthorOrForbidden)
错误发生原因的说明
要理解错误,需要查看get_permissions
GitHub 源代码中方法的实现:
#copy pasted from GitHub
def get_permissions(self):
"""
Instantiates and returns the list of permissions that this view requires.
"""
return [permission() for permission in self.permission_classes]
这里是从 中列出对象self.permission_classes
,意思permission_classes
是假设有类,而不是对象。
您正在向IsAuthorOrForbidden
权限类添加对象,您需要在其中添加类。如果你想覆盖,那么应该在这里完成:
class TextNoteGenerateShareKeyAPIView(generics.UpdateAPIView):
def get_permissions(self):
return [IsAuthenticated(), IsAuthorOrForbidden(modelClass=TextNote)]
但这是一个骇人听闻的解决方案,其中原始答案中的解决方案是在 DRF 中实施的正确方法。
推荐阅读
- java - 无法执行发送或更新操作,因为请求中传递的更改键与项目的当前更改键不匹配
- sql - Oracle SQL*Plus 获取每个 DISTINCT Branch_Id 值的最高 Cost_Maint 值
- server - 在大型大学安装 Moodle 的确切硬件要求是什么?
- mplab - ADC 不工作 PIC32MX795F512L MPLAB X IDE v5.20
- java - 对 StartUpWMClassName 的工具包反射访问警告
- python - CNN:当标签由地图给出时该怎么办
- c# - 如何在给定时间保持对对象状态的引用?
- python - 使用 Spacy,如何指示固定模式的一部分可以与模式的最后一部分用一个或多个单词分隔?
- php - WebService ERROR API 无法正常工作?
- django - 当前用户的 Django 动态初始值