Ronen Ness
Ronen Ness

Reputation: 10760

django rest post return 405 error code

I am using django with rest framework and I try to test POST on existing object but I keep getting 405. my ViewSet looks like this:

class Agents(viewsets.ModelViewSet):
    serializer_class = serializer.AgentSerializer
    model = serializer_class.Meta.model
    ....

and in the urls:

router = routers.SimpleRouter()
router.register(r'rest/agents', api_views.Agents, "Agent")
...
urlpatterns += router.urls

I call the post request from within APITestCase class (rest testing), my post request looks like this:

response = self.client.post(url, {'available': True, 'online':True}, format='json')

and printing url shows "/chat/rest/agents/1910_1567/", while 1910_1567 is the valid id of an existing agent (I create the agent during the setup and use its id).

I've seen other questions about rest post getting 405, but all the solutions there were url-related and in my case the url is correct. I even ran the setup outside the test and accessed the url via browser to get the object and the object indeed exist. but when I try to post to it - 405.

any ideas?

thanks!

Upvotes: 3

Views: 4906

Answers (2)

Linovia
Linovia

Reputation: 20996

POST are supposed to be for creation purpose. If you want to update with a ViewSet you'll need to PUT or PATCH (partial update) instead.

Edit: For more about this, here's some explanation on the HTTP methods used for REST API: http://restful-api-design.readthedocs.org/en/latest/methods.html

This is also described in the DRF documentation at: http://www.django-rest-framework.org/api-guide/routers/#simplerouter

Upvotes: 2

hspandher
hspandher

Reputation: 16763

Most probably your url is somehow matching with some different url's regex, and the request is being dispatched to some other view which disallows post request. Could you mention others urls in your urls.py? Infact you can verify this by adding pdb(debugger) in dispatch method of your view. If you made it to the pdb, then you can assume I was wrong.

If that is not the case, then you can evaluate the issue from dispatch method with debugger. Just in case you have any doubt about how to do that -

class Agents(viewsets.ModelViewSet):
     serializer_class = serializer.AgentSerializer
     model = serializer_class.Meta.model

     def dispatch(self, *args, **kwargs):
         import ipdb; ipdb.set_trace()
         return super(Agents, self).dispatch(*args, **kwargs)

Solution Found:-

You are passing id in url, so this request would be routed to detail view and detail view only allow GET, PUT, DELETE operations on resource since resource already exists. So to create resource, don't provide the id. Otherwise use PUT request and provide support for creation in PUT.

Upvotes: 3

Related Questions