Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set multiple permissions in one class view, depending on http request

I am working with django-rest-framework. The problem I am having is that the url is identical for both the POST and the GET methods but I want to have different permissions depending on which method is being called. Right now I'm using class based views and I can't figure out how to set different permissions depending on the method. What I want is if the user is an admin that they both POST and GET, if the user is authenticated than they can only GET, and if the user isn't authenticated they can't do anything.

class CategoryList(generics.ListCreateAPIView):
    queryset = QuestionCategory.objects.all()
    serializer_class = QuestionCategorySerializer
    permission_classes = (permissions.IsAuthenticated,)
like image 809
andrew13331 Avatar asked Dec 25 '22 08:12

andrew13331


2 Answers

Just an update.

You can override 'get_permissions' instead of 'get_queryset'.

For example:

def get_permissions(self):
    if self.request.method == 'GET':
        return [permissions.AllowAny()]
    elif self.request.method == 'DELETE':
        return [permissions.IsAdminUser()]
    else:  # PUT, PATCH
        return [...]

Note that 'get_permission' returns a list of permission instances, not classes.

like image 176
Adam Gu Avatar answered Jan 16 '23 00:01

Adam Gu


You could write it in a function to override default function to realize this.

use self.request to do this

class CategoryList(generics.ListCreateAPIView):
    serializer_class = QuestionCategorySerializer
    permission_classes = (permissions.IsAuthenticated,)

    def get_queryset(self):
        # this function used to get queryset
        # override this to judge request method

        if self.request.method == 'POST':
            self.permission_classes = (permissions.IsAdminUser,)

        return QuestionCategory.objects.all()

get_queryset: https://docs.djangoproject.com/en/dev/ref/class-based-views/mixins-multiple-object/#django.views.generic.list.MultipleObjectMixin.get_queryset

And you can write a get or post method in your generic view: https://docs.djangoproject.com/en/dev/topics/class-based-views/mixins/#using-singleobjectmixin-with-view

like image 24
WeizhongTu Avatar answered Jan 16 '23 00:01

WeizhongTu