python - Django REST 权限类不能在 OR 中一起工作,而是按预期独立工作
问题描述
我在使用 OR 运算符将两个权限放在一起时遇到了麻烦。文档说: Doc
如果它们从 rest_framework.permissions.BasePermission 继承,则可以使用标准 Python 位运算符组成权限。例如,IsAuthenticatedOrReadOnly 可以写成: ... permission_classes = [IsAuthenticated|ReadOnly]
所以我创建了权限:
permissions.py
class IsFullUserOrReadOnly(permissions.BasePermission):
"""
This class defines the permission to only allow the request to certain users with a
certain role."""
def has_permission(self, request, view):
"""
This function overrides the default has_permission method to allow the writing methods
only to full users or admin users
"""
if request.method in permissions.SAFE_METHODS:
return True
is_full_user = False
queryset = User.objects.get(email=request.user)
if queryset:
user = UserSerializer(queryset)
if 'roles' in user.data:
for role in user.data['roles']:
if role == ADMIN or role == FULL_USER:
is_full_user = True
print('IsFullUserOrReadOnly')
print(is_full_user)
print(request.method)
print(request.method =='POST')
return is_full_user or request.method =='POST'
class IsOwnerOrReadOnly(permissions.BasePermission):
"""
This class defines the permission to only allow the POST and PUT methods to the creator of
the item."""
def has_object_permission(self, request, view, obj):
"""
This function overrides the default has_object_permission method to allow the writing
methods to the owner of the object
"""
if request.method in permissions.SAFE_METHODS:
return True
# Instance must have an attribute named `created_by`.
print('IsOwnerOrReadOnly')
print(obj.created_by == request.user)
return obj.created_by == request.user
然后我将它们添加到我的视图中:
view.py
class ItemViewset(viewsets.ModelViewSet): # pylint: disable=too-many-ancestors
"""API Endpoint to return the list of items"""
queryset = Item.objects.all()
serializer_class = ItemSerializer
# permission_classes = (IsAuthenticated, IsFullUserOrReadOnly,)
permission_classes = [IsAuthenticated, IsFullUserOrReadOnly|IsOwnerOrReadOnly,]
# permission_classes = [IsAuthenticated, IsOwnerOrReadOnly]
两条注释行按预期工作,permission_classes
但是当我尝试将它们一起使用时,这意味着,作为一个完整用户或非安全方法的所有者,它总是允许一切。看起来那里没有条件了。
我不知道我是否遗漏了什么,但据我所知,这应该可行。我错过了什么吗?
解决方案
经过一些研究,我在此链接中发现了一个错误报告。作为一种解决方法,我将以下方法添加到IsFullUserOrReadOnly
:
def has_object_permission(self, request, view, obj):
"""
This function overrides the default has_object_permission to prevent the bug documented in:
https://github.com/encode/django-rest-framework/issues/7117
"""
return self.has_permission(request, view)
然后我将顺序切换为:
permission_classes = (IsAuthenticated, IsOwnerOrReadOnly|IsFullUserOrReadOnly,)
而且似乎确实可以解决问题
推荐阅读
- c# - c# CefSharp Flash 问题
- python - 动态创建实例时如何调用函数?
- html - aria-busy 和 aria-tomic 是干什么用的?
- regex - 在 Google Apps 脚本中;使用正则表达式和条件格式 - 创建 IPv4 地址验证器/检查器
- checkbox - Q 关于 Vuetify 复选框对齐
- java - Apache POI Word Table Cell 不更新颜色 (XWPFTableCell)
- r - 使用第二个 y 轴时如何分隔两个 geom_bar 样式
- c++ - 我正在尝试创建一个枚举,但出现“标识符预期错误”
- css - Safari 中的异常 Flexbox 行为
- tensorflow - 将 Tensorflow 对象检测 API (ssdlite_mobilenet_v3_small) 转换为 openvino IR 失败