Suppose that I have a Viewset named UserViewset, and I have assigned IsAuthenticated permission to UserViewset Viewset. Now, I want to create a normal method (not an action method), and I want to assign another permission to that method which is IsAdminUser, how would I do that?
Below is the code:
from rest_framework.viewsets import GenericViewSet
from rest_framework.permissions import IsAuthenticated, IsAdminUser
class UserViewset(GenericViewSet):
permission_classes = (IsAuthenticated,) # THIS IS THE DEFAULT PERMISSION I HAVE SET FOR THIS VIEWSET WHICH WILL APPLY TO ALL METHODS OR ACTION METHODS
def create(self, *args, **kwargs): # THIS IS MY CUSTOM METHOD
permission_classes = (IsAuthenticated, IsAdminUser) # I WANT SOMETHONG LIKE THIS, BUT IT DOES NOT WORK
.
.
.
def get_permissions(self):
# check the action and return the permission class accordingly
if self.action == 'create':
return [IsAdminUser(),]
return [IsAuthenticated(), ]
It will work only for action method. You can see that create() is normal method in my viewset. It does not have @action decoder.
In viewset opposite of APIView you are not able to use has_permission() or has_object_permission()…
it’s better to use it inside your methods like below:
class UserViewSet(viewsets.ViewSet):
permission_classes = [IsAuthenticated,]
queryset = User.objects.all()
def partial_update(self, request, pk=None):
user = get_object_or_404(self.queryset, pk=pk)
if user != request.user:
return Response({'permission denied': 'you are not the owner'})
srz_data = UserSerializer(instance=user, data=request.POST, partial=True)
if srz_data.is_valid():
srz_data.save()
return Response(data=srz_data.data)
return Response(data=srz_data.errors)
in nutshell you can use permissons in viewset in two ways: 1) as permission_classes = inside your viewset class(same as APIView)
which apply on whole methods in your viewset class 2) inside your class methods you limit the accessibilities of clients
This is just wrong. You can use has_permission inside a viewset.
class MyViewSet(viewsets.ViewSet):
permission_classes = [IsAuthenticated]
def has_permission(self, request, view):
action = view.action # list, retrieve, destroy, create, update, partial_update
has_perm = super().has_permission(request, view)
if not has_perm:
return False
if action in ("list", "retrieve"):
return user.has_perm("foo.has_read_perm")
# do some other checks