0

I'm pretty new to Django Rest Framework and I've been investigating this issue but can't find any solution. I'm pretty sure it will be a small detail but I'm out of idea.

I'm using DRF for a project. The team made the choice to not end URL paths with a ' / '. I have an endpoint linked to an APIView with a POST method. We want to do some stuff with a body sent in this POST. However calling it brings (Postman response):

405 Method Not allowed

{
    "detail": "Method \"POST\" not allowed."
}

Putting a ' / ' at the end of the URL path works (Postman response for normal behavior):

{
    "success": True,
    "message": "A message returned by the function in APIView"
}

urls.py

from django.urls import path, include
from runbook import views
from rest_framework.routers import DefaultRouter


router = DefaultRouter(trailing_slash=False)

router.register(r'my_objects', views.ObjectViewset)

urlpatterns = [
    path('', include(router.urls)),
    path('my_objects/myFunction',
         views.MyFunctionView.as_view(),
         name="my-function")

views.py

class MyFunctionView(APIView):
    """
    """
    def post(self, request, format=None):
        try:
            MyObject.objects.get(slug=slugify(request.data['candidate_name']))
        except MyObject.DoesNotExist:
            return Response(boolean_response(False))
        else:
            return Response(boolean_response(True))

What I read and tried:

  1. Wrong type of view: 405 "Method POST is not allowed" in Django REST framework ; 405 “Method POST is not allowed” in Django REST framework
  2. Use of slashes: 405 POST method not allowed ; How can I make a trailing slash optional on a Django Rest Framework SimpleRouter
  3. Potential indentation problem: django rest framework post method giving error "Method "POST" not allowed"
  4. Permissions: https://www.thetopsites.net/article/53705361.shtml
  5. APPEND_SLASH in settings.py: DRF post url without end slash ; https://docs.djangoproject.com/en/2.0/ref/settings/#append-slash

I also tried to:

  • Call with a '/' at the end even though the urls.py doesn't have one (new error: 404 Not found because URL is not the same)
  • Test in terminal instead of Postman (same errors)

Is it possible to make this request without '/'? Am I using Django tools wrong? Is there any subtlety I am not seeing ? So if anyone has a solution, advice or idea. Thank you !

Rfayolle
  • 3
  • 3
  • The `DefaultRouter` is creating some URL patterns for `ObjectViewset` class which are conflicting with `my_objects/myFunction` path – JPG Sep 21 '20 at 13:41
  • @ArakkalAbu you are right. I tested and indeed the router takes the priority and Django never "reach" the other pattern. I just learn that the order is important in ```urlpatterns``` thank you ! – Rfayolle Sep 21 '20 at 15:31

1 Answers1

0

So as said by @Arakkal Abu in the comment the router conflict with the other path in urlpatterns

Solution: send the router include at the end of the urlpatterns

router = DefaultRouter(trailing_slash=False)

router.register(r'my_objects', views.ObjectViewset)
urlpatterns = [
path('my_objects/myFunction',
     views.MyFunctionView.as_view(),
     name="my-function"),
path('', include(router.urls))
]

Indeed my_objects/myFunction is considered as part of the route my_objects/ where my_objects/myFunction/ is considered as a separate route and that's why it was working.

Rfayolle
  • 3
  • 3