Django/DRF - 405 Method not allowed on DELETE operation
Asked Answered
D

2

21

I'm working with two dev servers on my local machine (node & django's).

I've added django-cors-headers to the project to allow all origins & methods (on dev) with the following settings :

CORS_ORIGIN_ALLOW_ALL = 'ALL'
CORS_ALLOW_METHODS = (
        'GET',
        'POST',
        'PUT',
        'PATCH',
        'DELETE',
        'OPTIONS'
    )

I'm getting 405 when attempting DELETE. Looking at the response headers

HTTP/1.0 405 METHOD NOT ALLOWED
Date: Mon, 03 Nov 2014 10:04:43 GMT
Server: WSGIServer/0.1 Python/2.7.5
Vary: Cookie
X-Frame-Options: SAMEORIGIN
Content-Type: application/json
Access-Control-Allow-Origin: *
Allow: GET, POST, HEAD, OPTIONS

Notice that DELETE & PATCH / PUT are not present in the allowed methods list.

Is there something missing from my configuration ?

Doherty answered 3/11, 2014 at 10:12 Comment(4)
Does your view implement those methods? Are you using ModelViewSet? mixings, ApiView?Borisborja
good old viewsets.ModelViewSet - tests run perfectly.Doherty
What methods are allowed in your view? Due to docs CORS_ALLOW_METHODS define only methods that can be used globally, but not adding it to view automatically. One more thing CORS_ORIGIN_ALLOW_ALL must be boolean, not string.Punctual
@Punctual - You'r right - it's a boolean - changed it, same result. I guess I'm a bit confused about the difference between global and view level CORS definitions. Do you mind expanding on how can I allow DELETE on a specific view using the ModelViewset ? the delete method is working in the test so the view must allow it but the CORS headers are not updated in the response (what I though djagno-cors-header is supposed to do ... )Doherty
P
45

The response looks very similar to that of the list view (/api/resource/) for a ViewSet. List views only support GET, to list all of the objects, and POST to create a new object.

DELETE requests are only allowed on the detail view (/api/resource/1/). This is because Django REST Framework needs to know what object you are looking to delete, and this information cannot be retrieved from just the list view.

Plethoric answered 3/11, 2014 at 12:39 Comment(2)
Thanks man - That was it. I left out the pk from the url and the request went out to the list rather then the detail.Doherty
If using DRF router module then e.g. user-detail supports PUT operation and not user-list. django-rest-framework.org/api-guide/routersTannenbaum
D
15

If you need to connect http method DELETE with URL without pk in DRF try this inside of your ModelViewSet:

@action(methods=['delete'], detail=False)
def delete(self, request):
    # your code

UPD: Note that action attribute inside of ModelViewSet class will be None due request. If you check it somewhere, handle not only action name, but request method and request path.

Doddered answered 1/8, 2018 at 15:49 Comment(2)
this is the easiest way to do it.Escapade
I am facing the same issue. I am either getting 403 or 405 error with delete request. But adding @action decorator is not helping neither is @csrf_exemptGarrik

© 2022 - 2024 — McMap. All rights reserved.