I have an private
action decorator for a User View. I want the action to be accessible only for the User in question.
# views.py
class UserViewSet(viewsets.ModelViewSet):
queryset = get_user_model().objects.all()
serializer_class = UserSerializer
@action(detail=True, permission_classes=[IsSelf])
def private(self, request, pk):
user = get_object_or_404(get_user_model(), pk=pk)
data = UserPrivateSerializer(user).data
return Response(data, status=status=HTTP_200_OK)
# permissions.py
class IsSelf(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
return obj == request.user
However, it looks like anyone can go to my private
action - even if I explicitly declare IsSelf
to be False
:
class IsSelf(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
# This has no effect
return False
What am I missing?
CodePudding user response:
FYI:
The instance-level has_object_permission(...)
method will only be called if the view-level has_permission(...)
checks have already passed. Since it is inherited from BasePermission
, the has_permission(...)
is already returning the True
value.
The has_object_permission(...)
method is getting called when you call the .get_object()
method of the GenericAPIView
.
class UserViewSet(viewsets.ModelViewSet):
queryset = get_user_model().objects.all()
serializer_class = UserSerializer
@action(detail=True, permission_classes=[IsSelf])
def private(self, request, *args, **kwargs):
user = self.get_object()
data = UserPrivateSerializer(user).data
return Response(data, status=status.HTTP_200_OK)