Request method mapping is happening after permission check.

19 views
Skip to first unread message

DIPENDRA BHATT

unread,
Oct 23, 2019, 9:00:39 AM10/23/19
to Django REST framework
So, this issue is something that i faced while testing of my class based views. I had a view that creates and updates user as shown below.




class UserViewSet(ViewSet):

def check_permissions(self, request):
print("Action = ", self.action)
if self.action == 'create_user':
return True
return super().check_permissions(request)

def create_user(self, request):
# user creation code

def update(self, request):
#user update code





And create_user was mapped with POST method and update was mapped with PUT method. So, my need was that for create_user action no permission is required and for update, user should be authenticated. Overriding check_permssion did the job. Now, when i was testing the create_user end point. I wrote a test that tries to create user using some method other than POST. I expected that the response should be HTTP_405_METHOD_NOT_ALLOWED. 


def test_create_user_with_invalid_method(self):
data = self.user_data
response = self.client.get(self.url, data)
self.assertEqual(response.status_code, HTTP_405_METHOD_NOT_ALLOWED)


But the response was HTTP_401_UNAUTHORIZED. And the action variable was set as None. My url mapping is like this

url(r'^account/register/$', UserViewSet.as_view({"post": "create_user"}), name="account_register_view"),

So looking at this, i thought djago is either doing the mapping of request(method, url) to action either after checking permission or doing it before but setting action as None when it fails to find the proper mapping

So my concern is that whether this is the correct behaviour, or am i doing something logically wrong here.

PS: Please ignore my grammatical mistaks.

Thanks



Jason

unread,
Oct 24, 2019, 10:26:34 AM10/24/19
to Django REST framework
Good question!

the answer lies in dispatch

        try:
            self.initial(request, *args, **kwargs)

            # Get the appropriate handler method
            if request.method.lower() in self.http_method_names:
                handler = getattr(self, request.method.lower(),
                                  self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed



So, due to this, the permission check occurs before the request method handler is resolved

DIPENDRA BHATT

unread,
Oct 24, 2019, 10:48:45 AM10/24/19
to Django REST framework
Ok, yeah i checked that now. But now another issue is, if i try to send any request other than post to create_user, why is the action variable set as none. But if i send the authentication headers that time the action variables is properly set.
Reply all
Reply to author
Forward
0 new messages