"detail": "method delete not allowed" django

Question:

I made a view that can use put, delete request using modelviewset and mapped it with url. I have clearly made it possible to request put and delete request to url, but if you send delete request to url, I return 405 error. What’s wrong with my code? Here’s my code.

views.py

class UpdateDeletePostView (ModelViewSet) :
    serializer_class = PostSerializer
    permission_classes = [IsAuthenticated, IsOwner]
    queryset = Post.objects.all()

    def update (self, request, *args, **kwargs) :
        super().update(request, *args, **kwargs)
        return Response({'success': '게시물이 수정 되었습니다.'}, status=200)

    def destroy (self, request, *args, **kwargs) :
        super().destroy(request, *args, **kwargs)
        return Response({'success': '게시물이 삭제 되었습니다.'}, status=200)

feedurls.py

path('post/<int:pk>', UpdateDeletePostView.as_view({'put': 'update', 'delete': 'destroy'})),

serverurls.py

path('feed/', include('feed.urls')),

and error

"detail": "method delete not allowed"
Asked By: leedjango

||

Answers:

as I wrote in the comment looks like you don’t need a ViewSet because you are handling just operations on a single item.
In general you can restrict the operations available for Views or ViewSet using proper mixins.

I suggest two possible approaches

Use Generic View

class UpdateDeletePostView(
        UpdateModelMixin,
        DeleteModelMixin,
        GenericAPIView):
    .....

and

urlpatterns = [
    path('post/<int:pk>', UpdateDeletePostView.as_view()),
    ...
]

Use ViewSet and Router

class UpdateDeletePostViewSet(
        UpdateModelMixin,
        DeleteModelMixin,
        GenericViewset):
    .....
router = SimpleRouter()
router.register('feed', UpdateDeletePostViewSet)

urlpatterns = [
    path('', include(router.urls)),
    ...
]
Answered By: Massimo Costa

TLDR;

Use the detail-item endpoint instead of the list-items endpoint.

http://127.0.0.1:8000/api/items/<item-id>/

instead of

http://127.0.0.1:8000/api/items/


This happened with a project I was working on. Turns out I was trying to PUT, PATCH, DELETE from the list-items endpoint rather than the detail-item endpoint.

If you implemented your viewset using the ModelViewSet class, and your GET and POST methods work. Chances are you may be using the wrong endpoint.

Example:
If you’re trying to retrieve all your products from you use the list-items endpoint which will look something like:
http://127.0.0.1:8000/api/product/

If you’re trying to get the detail of a specific item, you use the detail-item endpoint which looks like:
http://127.0.0.1:8000/api/product/2/

Where 2 is the id of the specific product that you’re trying to PUT, PATCH, or DELETE. The reason you get the 405 is because it is your fault (not the servers fault), that you’re applying item-level methods to an endpoint that provides lists of items – making your request ambiguous.

Answered By: zoot-io