Here is my permission class:
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
To follow an object, you have to use the follow
action. This is my viewset:
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)
The issue is, when I try to follow an object, it gives me a 403_FORBIDDEN
status code. I'm assuming this is because in has_permission
, I have to add this line:
if view.action=='follow':
return True
But even if I add that line, I get a 403_FORBIDDEN
error when an owner tries to PUT to his own object (this is probably because in my has_permission
method I don't have if view.action == 'update': return True
but PUT, PATCH and DELETE all depend on the object itself (if obj.owner == request.user
) so how do I properly allow only users to PUT, PATCH and DELETE while allowing any users to FOLLOW objects (FOLLOW is also an object level permission so placing that in has_permission
doesn't make sense to me since it has to do with objects).