How do I use permission_classes in a custom method of a Viewset in Django?

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
        .
        .
        .

You can Override Get-permission class

 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.

@Bridgstoneic that is the issue, I want to use custom permission in ViewSet for a normal method, not an action method.

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

This “action” and other parameters are documented here.