405 POST方法不允许

56

我正在尝试使用OAuth开发REST提供程序。 我使用Django RESTFramework和DjangoOAuthToolkit。 我执行了一个GET请求,它可以完美地工作,但我正在尝试使用POST请求,服务器响应{"detail": "Method 'POST' not allowed."}。

# views.py
@api_view(['POST'])
def pruebapost(request):
    usuario = User()
    access_token = Token.objects.get(
        key=request.POST['oauth_token']
    )
    usuario = access_token.user
    content = {'saludo': usuario.username}
    return Response(content)

# settings.py
OAUTH_AUTHORIZE_VIEW = 'principal.views.oauth_authorize'
SESSION_SERIALIZER = 'django.contrib.sessions.serializers.JSONSerializer'
REST_FRAMEWORK = {
   'DEFAULT_RENDERER_CLASSES': (
        'rest_framework.renderers.JSONRenderer',
    ),
   'DEFAULT_PARSER_CLASSES': (
        'rest_framework.parsers.JSONParser',
    ),
   'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.OAuthAuthentication',
    ),
}

我正在使用这个作为一个“测试”客户端:

import urlparse
import oauth2 as oauth
import requests

consumer_key = "clave"
consumer_secret = "secreto"
consumer = oauth.Consumer(consumer_key, consumer_secret)
client = oauth.Client(consumer)
resource_url = 'http://blablabla.pythonanywhere.com/prueba'
consumer = oauth.Consumer(key='clave', secret='secreto')
token = oauth.Token(key='e7456187a43141af8d2e0d8fa99b95b9',
                    secret='3wRIKoacff16tcew')

oauth_request = oauth.Request.from_consumer_and_token(
    consumer,
    token,
    http_method='POST',
    http_url=resource_url,
    parameters={'hola':'pepe'}
)
oauth_request.sign_request(
    oauth.SignatureMethod_HMAC_SHA1(),
    consumer,
    token
)
url = oauth_request.to_url()
response = requests.post(url, oauth_request.to_postdata())
print response.content

我不明白REST框架文档中关于405方法不允许的解释是什么意思。

“当发生一个请求无法映射到视图处理方法时引发此异常。”

谢谢


4
这个错误基本上意味着你没有允许特定的HTTP方法在特定的视图上被调用,或者更常见的情况是你正在调用一个错误的URL。请检查是否调用了正确的URL,并可以在此提供你的URL配置。 - Ania Warzecha
6
问题解决了,我在 URL 上漏掉了一个斜杠。非常新手的问题。谢谢! - ecorzo
1
可能是重复的问题:Django/DRF - DELETE操作返回405 Method not allowed错误 - Kevin Brown-Silva
在我的情况下,端点甚至都不可用。我忘记将其添加到urls.py中了。非常令人困惑。 - elena
4个回答

71

这个问题在评论区被 user2663554 解决了。

问题已解决,我在url上漏掉了一个斜杠。

这个响应代码(405)可能来自许多问题,但通常要么是您正在使用错误的URL(像在这种情况下一样),要么是您正在使用错误的请求方法。有时两者都有!

经常看到人们在尝试更新个别资源(/api/res/1)时遇到此问题,但他们实际上在使用列表URL (/api/res),这将使请求无法成功发送。反过来也可能发生,即有人试图创建新实例,但他们将POST请求发送到单个对象。

在某些情况下,使用了错误的URL,因此用户请求了标准的非API视图,并认为它是API视图(/res而非/api/res)。因此,请始终检查您的URL!


7
在我的情况下,我使用的是http而不是https,但是您的回答帮助我理清了思路。 - Bojan Kogoj

21

在我的情况下,我有一个与基本URL相同的路由器。

router.register('sales', SalesViewSet, basename='sales')

我的url模式是

urlpatterns = [
    path('', include((router.urls, app_name))),
    path('sales/analytics/', Analytics.as_view(), name='create'),
]

我在sales/analytics/处遇到了405错误。解决方法是更改urlpatterns的顺序。

urlpatterns = [
    path('sales/analytics/', Analytics.as_view(), name='create'),
    path('', include((router.urls, app_name))),
]

3
class ApiIndexView(APIView)

请使用 "import from rest_framework import generics" 替代此代码,并作出以下更改:

class ApiIndexView(generics.ListCreateAPIView) 

在通用列表创建API视图中有许多视图,其中listcreateAPIview用于获取和发布,而createapiview仅用于发布方法。


2

这是我在SO上的第一个答案。在尝试了所有方法并且过去6个小时一直很沮丧后,终于有了灵感,我发现还有另一个原因导致此问题; 简单来说,我没有登录到/admin。 我登录到/admin,解决了“HTTP 405方法不允许”问题,即帖子视图无法显示。我希望这能帮助任何遇到这种问题的人。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接