【问题标题】:DjangoRestFramework - How to properly seperate has_permission and has_object_permissionDjangoRestFramework - 如何正确分离 has_permission 和 has_object_permission
【发布时间】:2023-03-23 20:30:01
【问题描述】:

这是我的权限类:

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 对象(FOLLOW 也是对象级别的权限,因此将其放在 has_permission对我来说没有意义,因为它与对象有关)。

【问题讨论】:

    标签: django django-rest-framework django-permissions


    【解决方案1】:

    您无需覆盖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
    

    这样所有者和员工可以执行任何操作。但用户只能获取、发布和关注。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-21
      • 2015-03-31
      • 1970-01-01
      • 2020-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-11
      相关资源
      最近更新 更多