DjangoRestFramework - 由于某种原因不允许对象级别权限(has_permission和has_object_permission)

时间:2015-11-02 23:03:26

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

这是我的许可:

class IsFllowOrAdminUserOrReadOnly(permissions.BasePermission):
    """
    Allow any users to follow objects and ReadOnly. Allow all requests for
    admin users.
    """
    def has_permission(self, request, view):
        return request.method in permissions.SAFE_METHODS or request.user.is_staff

    def has_object_permission(self, request, view, obj):
        # Allow watching objects.
        if view.action=='follow':
            return True

        return request.method in permissions.SAFE_METHODS or request.user.is_staff

这是我的观点(并采取行动):

class PageViewSet(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错误:

if view.action=='follow':
    return True

知道我应该如何解决这个问题吗?

请注意,此问题与我之前发布的问题不同:DjangoRestFramework - How to properly seperate has_permission and has_object_permission因为此权限仅允许管理员用户创建对象,而其他帖子允许任何用户创建对象。

1 个答案:

答案 0 :(得分:1)

detail_route请求或POST请求无法访问has_object_permission。只有PUT, PATCH, DELETE才能达到has_object_permission

所以试试:

def has_permission(self, request, view):
    if request.user.is_authenticated() and view.action=='follow':
        return True
    return request.method in permissions.SAFE_METHODS or request.user.is_staff

def has_object_permission(self, request, view, obj):
    return request.method in permissions.SAFE_METHODS or request.user.is_staff

这将允许:

  • 未经身份验证的用户只读
  • 认证用户只读& follow
  • 管理员可以执行任何请求