# How do I use permission\_classes in a custom method of a Viewset in Django?

**URL:** <https://forum.djangoproject.com/t/how-do-i-use-permission-classes-in-a-custom-method-of-a-viewset-in-django/17127>\
**Category:** Forms & APIs\
**Created:** [November 19, 2022, 12:52am UTC](https://forum.djangoproject.com/t/how-do-i-use-permission-classes-in-a-custom-method-of-a-viewset-in-django/17127 "2022-11-19T00:52:12Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![khaw235](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/khaw235/32/6372_2.png) [@khaw235](https://forum.djangoproject.com/u/khaw235)\
**Post date:** [November 19, 2022, 12:52am UTC](https://forum.djangoproject.com/t/how-do-i-use-permission-classes-in-a-custom-method-of-a-viewset-in-django/17127/1 "2022-11-19T00:52:12Z")

</div>

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:

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

```

---

<div class="post-metadata">

**Author:** ![Bridgstoneic](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/bridgstoneic/32/11031_2.png) [@Bridgstoneic](https://forum.djangoproject.com/u/Bridgstoneic)\
**Post date:** [November 24, 2022, 11:48am UTC](https://forum.djangoproject.com/t/how-do-i-use-permission-classes-in-a-custom-method-of-a-viewset-in-django/17127/2 "2022-11-24T11:48:51Z")

</div>

You can Override Get-permission class

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

---

<div class="post-metadata">

**Author:** ![khaw235](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/khaw235/32/6372_2.png) [@khaw235](https://forum.djangoproject.com/u/khaw235)\
**Post date:** [November 24, 2022, 1:26pm UTC](https://forum.djangoproject.com/t/how-do-i-use-permission-classes-in-a-custom-method-of-a-viewset-in-django/17127/3 "2022-11-24T13:26:02Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![ventuno-21](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/ventuno-21/32/28531_2.png) [@ventuno-21](https://forum.djangoproject.com/u/ventuno-21)\
**Post date:** [May 16, 2025, 8:18am UTC](https://forum.djangoproject.com/t/how-do-i-use-permission-classes-in-a-custom-method-of-a-viewset-in-django/17127/4 "2025-05-16T08:18:14Z")

</div>

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:

```auto
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

---

<div class="post-metadata">

**Author:** ![leandrodesouzadev](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/leandrodesouzadev/32/8981_2.png) [@leandrodesouzadev](https://forum.djangoproject.com/u/leandrodesouzadev)\
**Post date:** [May 16, 2025, 11:08am UTC](https://forum.djangoproject.com/t/how-do-i-use-permission-classes-in-a-custom-method-of-a-viewset-in-django/17127/5 "2025-05-16T11:08:18Z")

</div>

> [@ventuno-21](#):
>
> In viewset opposite of APIView you are not able to use **has\_permission()** or **has\_object\_permission()**…

This is just wrong. You can use `has_permission` inside a viewset.

```auto
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](https://www.django-rest-framework.org/api-guide/viewsets/#introspecting-viewset-actions).
