405 “Method POST is not allowed” in Django REST fr

2019-04-19 12:22发布

问题:

I am new in Django REST framework. Can someone explain why I get such error, if I make a POST request to '/api/index/'

405 Method Not Allowed
{"detail":"Method \"POST\" not allowed."}

My code is following:

# views.py
class ApiIndexView(APIView):
    permission_classes = (permissions.AllowAny,)

    def post(self, request, format=None):
        return Response("ok")

# urls.py
urlpatterns = [
    url(r'^api/index/$', views.ApiIndexView.as_view()),
]

# settings.py
REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.DjangoModelPermissions',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.TokenAuthentication',
    )
}

But if I add <pk> into my pattern, everything works fine:

# views.py
class ApiIndexView(APIView):
    permission_classes = (permissions.AllowAny,)

    def post(self, request, pk, format=None):
        return Response("ok")

# urls.py
urlpatterns = [
    url(r'^api/index/(?P<pk>\d+)/$', views.ApiIndexView.as_view()),
]

I am completely confused. Why it's necessary to use <pk> and is there a way to avoid the use of this parameter in the URL pattern?

回答1:

You need to change just:

# views.py
class ApiIndexView(UpdateView):
    permission_classes = (permissions.AllowAny,)

    def post(self, request, format=None):
        return Response("ok")


回答2:

Make sure that you have "POST" in http_method_names. Alternatively, you can write it like this:

def allowed_methods(self):
    """
    Return the list of allowed HTTP methods, uppercased.
    """
    self.http_method_names.append("post")
    return [method.upper() for method in self.http_method_names
            if hasattr(self, method)]


回答3:

class ApiIndexView(APIView) 

instead of this please import from rest_framework import generics and change it to

class ApiIndexView(generics.ListCreateAPIView) 

There are many generic views. ListCreateAPIView is used for GET and POST and CreateAPIView is used only for POST methods