【问题标题】:django rest post return 405 error codedjango rest post返回405错误代码
【发布时间】:2015-08-31 23:29:45
【问题描述】:

我正在使用带有 rest 框架的 django,我尝试在现有对象上测试 POST,但我不断收到 405。我的 ViewSet 看起来像这样:

class Agents(viewsets.ModelViewSet):
    serializer_class = serializer.AgentSerializer
    model = serializer_class.Meta.model
    ....

在网址中:

router = routers.SimpleRouter()
router.register(r'rest/agents', api_views.Agents, "Agent")
...
urlpatterns += router.urls

我从 APITestCase 类(休息测试)中调用发布请求,我的发布请求如下所示:

response = self.client.post(url, {'available': True, 'online':True}, format='json')

打印 url 显示“/chat/rest/agents/1910_1567/”,而 1910_1567 是现有代理的有效 id(我在设置期间创建代理并使用它的 id)。

我已经看到其他关于休息帖子获得 405 的问题,但那里的所有解决方案都与 url 相关,在我的情况下,url 是正确的。我什至在测试之外运行设置并通过浏览器访问 url 以获取对象并且对象确实存在。但是当我尝试发布到它时 - 405.

有什么想法吗?

谢谢!

【问题讨论】:

  • PS 我认为它很明显,但是当我覆盖 update() 函数并添加 print 时, print 永远不会被调用,例如,我得到 405 不是来自 update 的实现,而是在此之前。真的看起来像 url 相关的,但我验证了 url 并且它没问题:/
  • 尾部斜杠应该在那里吗?如果你设置router = SimpleRouter(trailing_slash=False)呢?
  • @Railslide 帖子网址通常以斜杠结尾,但我确实尝试了您的建议并得到了相同的结果。
  • 如果你卷曲到它会怎样?
  • @Railslide 我不明白——“卷曲”是什么意思?谢谢:)

标签: django django-rest-framework


【解决方案1】:

POST 应该用于创建目的。如果您想使用 ViewSet 进行更新,则需要 PUT 或 PATCH(部分更新)。

编辑: 关于这一点的更多信息,这里有一些关于用于 REST API 的 HTTP 方法的解释: http://restful-api-design.readthedocs.org/en/latest/methods.html

这也在 DRF 文档中有所描述: http://www.django-rest-framework.org/api-guide/routers/#simplerouter

【讨论】:

  • 你确定吗?您可以添加文档参考的链接吗?谢谢:)
  • 当然,这在路由器部分有描述:django-rest-framework.org/api-guide/routers/#simplerouter
  • 确实你是对的。我习惯休息接受“发布”作为更新现有对象的方式的api,我猜django-rest对此更严格......谢谢!
【解决方案2】:

很可能您的 url 以某种方式与某些不同 url 的正则表达式匹配,并且请求被分派到其他不允许发布请求的视图。您能否在您的 urls.py 中提及其他网址?事实上,您可以通过在视图的调度方法中添加 pdb(debugger) 来验证这一点。如果你成功了 pdb,那么你可以认为我错了。

如果不是这样,那么您可以使用调试器从调度方法评估问题。以防万一您对如何执行此操作有任何疑问 -

class Agents(viewsets.ModelViewSet):
     serializer_class = serializer.AgentSerializer
     model = serializer_class.Meta.model

     def dispatch(self, *args, **kwargs):
         import ipdb; ipdb.set_trace()
         return super(Agents, self).dispatch(*args, **kwargs)

找到的解决方案:-

您在 url 中传递 id,因此该请求将被路由到详细视图,并且详细视图仅允许对资源进行 GET、PUT、DELETE 操作,因为资源已经存在。所以要创建资源,不要提供 id。否则使用 PUT 请求并提供在 PUT 中创建的支持。

【讨论】:

  • 感谢 hspandher,但这不是问题所在。命名空间“/chat/rest”对于这个对象 api 是唯一的,只是为了确保我在上面一行添加了对相同 url 的 get() 调用,它可以正常工作并正确返回代理对象。 (我宁愿不发布网址,因为它有点长,我不想在问题中添加“噪音”)
  • 感谢调试示例!我调试了 dispatch 发现 ViewSet 对象没有 post 方法!由于这一行,它返回 405:handler = getattr(self, request.method.lower(), self.http_method_not_allowed),其中 request.method 确实是 post。那么,如果我使用了viewsets.ModelViewSet,为什么我的ViewSet 中没有帖子呢?有什么想法吗?谢谢! :)
  • 是只发生在测试中还是浏览器中??
  • 也在浏览器中,使用休息框架默认视图我得到“”详细信息“:“方法\“POST\”不允许。“”。编辑:我在标题数据中看到“允许:GET、PUT、PATCH、HEAD、OPTIONS”,一旦我将 post() 方法添加到我的 ViewSet 对象并刷新,“POST”就会添加到允许列表中。有道理,但是 post() 应该是为 ModelViewSet 自动创建的,不是吗?
猜你喜欢
  • 2016-04-29
  • 2018-06-29
  • 2015-04-26
  • 2016-01-10
  • 2017-09-19
  • 2022-08-03
  • 2011-12-10
  • 2016-05-03
  • 1970-01-01
相关资源
最近更新 更多