2015-11-01 129 views
0

这里是我的权限类:DjangoRestFramework - 如何正确单独has_permission和has_object_permission

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 

但是,即使我再补充一点线,我得到一个403_FORBIDDEN错误时所有者试图把自己的对象(这是可能是因为在我的has_permission方法中,我没有if view.action == 'update': return True,但PUT,PATCH和DELETE全部取决于对象本身(if obj.owner == request.user),所以如何在允许任何用户加关注对象的情况下只允许用户输入PUT,PATCH和DELETE(FOLLOW也是一个对象级别的权限,因此在has_permission中对我没有意义,因为它与对象有关)。

回答

0

您不需要重写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 

这样,业主和工作人员可以执行任何动作。但用户只能获取,发布和关注。