django-rest-framework如何决定`ModelViewSet`的默认`allowed_methods`应该是什么?

时间:2016-03-21 21:59:29

标签: python django django-rest-framework

我工作的公司有2个使用django和DRF 3的项目。

  • 这两个项目都有一个扩展ModelViewSet
  • 的ViewSet
  • 两个ViewSets都没有明确定义allowed_methods属性,只是使用任何DRF数字应该是默认值
  • 两个ViewSets都不会覆盖或定义任何处理程序方法(create()update()partial_update()patch()等。)

但是,在一个项目中,allowed_methods属性默认为[u'GET', u'PUT', u'PATCH', u'DELETE', u'HEAD', u'OPTIONS']。其他allowed_methods默认为[u'GET', u'POST', u'HEAD', u'OPTIONS']。因此,我得到了一个405响应

  

方法" PATCH"不允许。

当我尝试发送PATCH请求时。

是什么原因导致项目2受到更多限制?

2 个答案:

答案 0 :(得分:3)

DRF only exposes Django的内部_allowed_methods()因此我们应该审核that method的实施情况:

def _allowed_methods(self):
    return [m.upper() for m in self.http_method_names if hasattr(self, m)]

其中self.http_method_names定义为:

http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']

这些条款定义的哪些方法可以解释您所看到的内容是否存在差异?

答案 1 :(得分:2)

答案简短:

就我而言,我不小心将PATCH发送到了list网址,而不是put/patch网址。


答案越长:

我发现问题不是一个项目对allowed_methods有不同的默认值,而是ViewSet的action_mapallowed_methods属性发生了变化您点击了哪个ViewSet网址,因为action_map受路由器影响(请参阅SimpleRouter.routes)。

因此,如果您尝试点击" // [base_url] / your-model /"与我PATCHPUT一样,它会说仅允许['GET', 'POST', 'HEAD', 'OPTIONS']patch()不会与partial_update()相关联,即使它使用相同的ViewSet类,并且该类中存在partial_update()

如果您想发送PATCH,则必须将其发送至" // [base_url] / your-model / [some_id] /"。