Django Rest Framework - 如何正确分离 has_permission 和 has_object_permission
DjangoRestFramework - How to properly seperate has_permission and has_object_permission
这是我的许可 class:
class IsCreationOrFollowOrOwnerOrReadOnly(permissions.BasePermission):
"""
Allow any users to create, get and follow objects. Allow only owners to
PUT, PATCH and DELETE.
"""
def has_permission(self, request, view):
if request.method in permissions.SAFE_METHODS or request.user.is_staff:
return True
if view.action == 'create':
return True
return False
def has_object_permission(self, request, view):
if request.method in permissions.SAFE_METHODS or request.user.is_staff or view.action=='follow':
return True
try:
return obj.owner == request.user
except:
return obj == request.user # If obj Is request.user
要跟随对象,您必须使用 follow
操作。这是我的视图集:
class {ageViewSet(viewsets.ModelViewSet):
queryset = Page.objects.all()
serializer_class = PageSerializer
permission_classes = (IsAuthenticated, IsCreationOrFollowOrOwnerOrReadOnly,)
def perform_create(self, serializer):
serializer.save(owner=self.request.user, location=self.request.user.userextended.location)
@detail_route(methods=['post'])
def follow(self, request, pk=None):
page = self.get_object()
page.users.add(request.user)
return Response(status=status.HTTP_204_NO_CONTENT)
问题是,当我尝试关注一个对象时,它给了我一个 403_FORBIDDEN
状态代码。我假设这是因为在 has_permission
中,我必须添加这一行:
if view.action=='follow':
return True
但是即使我添加了那一行,当所有者试图 PUT 到他自己的对象时我也会得到一个 403_FORBIDDEN
错误(这可能是因为在我的 has_permission
方法中我没有if view.action == 'update': return True
但是 PUT、PATCH 和 DELETE 都取决于对象本身 (if obj.owner == request.user
) 那么我如何正确地只允许用户 PUT、PATCH 和 DELETE 而允许任何用户关注对象(FOLLOW 也是一个对象级权限,因此将其放在 has_permission
中对我来说没有意义,因为它与对象有关)。
您不需要覆盖 has_permission
。只需覆盖 has_object_permission
并执行以下操作:
def has_object_permission(self, request, view, obj):
if request.method in permissions.SAFE_METHODS or request.user.is_staff or obj.owner == request.user:
return True
if request.method=='POST':
return True
return False
这样所有者和员工可以执行任何操作。但是一个用户只能获取,post和关注
这是我的许可 class:
class IsCreationOrFollowOrOwnerOrReadOnly(permissions.BasePermission):
"""
Allow any users to create, get and follow objects. Allow only owners to
PUT, PATCH and DELETE.
"""
def has_permission(self, request, view):
if request.method in permissions.SAFE_METHODS or request.user.is_staff:
return True
if view.action == 'create':
return True
return False
def has_object_permission(self, request, view):
if request.method in permissions.SAFE_METHODS or request.user.is_staff or view.action=='follow':
return True
try:
return obj.owner == request.user
except:
return obj == request.user # If obj Is request.user
要跟随对象,您必须使用 follow
操作。这是我的视图集:
class {ageViewSet(viewsets.ModelViewSet):
queryset = Page.objects.all()
serializer_class = PageSerializer
permission_classes = (IsAuthenticated, IsCreationOrFollowOrOwnerOrReadOnly,)
def perform_create(self, serializer):
serializer.save(owner=self.request.user, location=self.request.user.userextended.location)
@detail_route(methods=['post'])
def follow(self, request, pk=None):
page = self.get_object()
page.users.add(request.user)
return Response(status=status.HTTP_204_NO_CONTENT)
问题是,当我尝试关注一个对象时,它给了我一个 403_FORBIDDEN
状态代码。我假设这是因为在 has_permission
中,我必须添加这一行:
if view.action=='follow':
return True
但是即使我添加了那一行,当所有者试图 PUT 到他自己的对象时我也会得到一个 403_FORBIDDEN
错误(这可能是因为在我的 has_permission
方法中我没有if view.action == 'update': return True
但是 PUT、PATCH 和 DELETE 都取决于对象本身 (if obj.owner == request.user
) 那么我如何正确地只允许用户 PUT、PATCH 和 DELETE 而允许任何用户关注对象(FOLLOW 也是一个对象级权限,因此将其放在 has_permission
中对我来说没有意义,因为它与对象有关)。
您不需要覆盖 has_permission
。只需覆盖 has_object_permission
并执行以下操作:
def has_object_permission(self, request, view, obj):
if request.method in permissions.SAFE_METHODS or request.user.is_staff or obj.owner == request.user:
return True
if request.method=='POST':
return True
return False
这样所有者和员工可以执行任何操作。但是一个用户只能获取,post和关注