django rest framework - 对象权限不会触发

时间:2017-03-13 03:12:36

标签: django django-rest-framework

我有以下设置:

permission.py

def get_permission_level(request, obj):
    try:
        level = PasswordListACL.objects.get(list=obj, user=request.user)
    except PasswordListACL.DoesNotExist:
        level = None
    return level


class IsPasswordListOwner(permissions.DjangoObjectPermissions):

    def has_permission(self, request, view):
        return True

    def has_object_permission(self, request, view, obj):
        print(get_permission_level(request, obj))
        if get_permission_level(request, obj) == None:
            print('false')
            return False
        else:
            level = AccessLevel.objects.get(pk=get_permission_level(request, obj).level_id).name
            if level == 'Owner':
                return True
            else:
                return False

我可以通过我的print('false')确认正在执行权限并且它返回正确的值(我期待False)但是视图仍然返回数据而不是403。

views.py

class PasswordListViewSet(viewsets.ModelViewSet):
    queryset = PasswordList.objects.all()
    serializer_class = PasswordListSerializer
    permission_classes = (IsPasswordListOwner,)

    def list(self, request):
        self.permission_classes = [IsPasswordListOwner, ]
        queryset = self.get_queryset().filter(passwordlistacl__user=request.user)
        serializer = PasswordListSerializer(queryset, many=True, context={'request': request})
        return Response(serializer.data)

    def retrieve(self, request, pk=None):
        self.permission_classes = [IsPasswordListOwner, ]
        queryset = self.get_queryset()
        if get_object_or_404(queryset, pk=pk):
            password = get_object_or_404(queryset, pk=pk)
        else:
            pass
        serializer = PasswordListSerializer(password, context={'request': request})
        return Response(serializer.data)

修改 - 更改has_permission上的回报确认覆盖我has_object_permission的权限?

这样做给了我403(正确):

def has_permission(self, request, view):
    return False

1 个答案:

答案 0 :(得分:2)

documentation州:

  

如果您正在编写自己的视图并希望强制执行对象级别权限,或者在通用视图上覆盖get_object方法,那么您需要显式调用.check_object_permissions(request,obj)方法。在您检索对象的位置查看。

因为您没有致电get_object(),所以您需要在某个时候致电self.check_object_permissions(self.request, obj)