简体   繁体   English

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

[英]How does django-rest-framework decide what the default `allowed_methods` should be for a `ModelViewSet`?

The company I work for has 2 projects that use django and DRF 3. 我工作的公司有2个使用django和DRF 3的项目。

  • both projects have a ViewSet that extends ModelViewSet 这两个项目有延伸的视图集中ModelViewSet
  • both ViewSets do not explicitly define the allowed_methods property and are just using whatever DRF figures should be the default 两个ViewSets都没有明确定义allowed_methods属性,只是使用任何DRF数字应该是默认值
  • both ViewSets do not override or define any handler methods ( create() , update() , partial_update() , patch() , etc.) 两个ViewSets都不会覆盖或定义任何处理程序方法( create()update()partial_update()patch()等)

However, in one project the allowed_methods property defaults to [u'GET', u'PUT', u'PATCH', u'DELETE', u'HEAD', u'OPTIONS'] . 但是,在一个项目中, allowed_methods属性默认为[u'GET', u'PUT', u'PATCH', u'DELETE', u'HEAD', u'OPTIONS'] For the other allowed_methods defaults to [u'GET', u'POST', u'HEAD', u'OPTIONS'] . 对于其他allowed_methods默认为[u'GET', u'POST', u'HEAD', u'OPTIONS'] Consequently, I get a 405 response with 因此,我获得了405响应

Method "PATCH" not allowed. 方法“PATCH”不允许。

when I attempt to send a PATCH request. 当我尝试发送PATCH请求时。

What causes project 2 to be more restricted? 是什么原因导致项目2受到更多限制?

DRF only exposes Django's internal _allowed_methods() so we should review the implementation of that method : DRF 只暴露 Django的内部_allowed_methods()因此我们应该检查该方法的实现:

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

where self.http_method_names is defined as: 其中self.http_method_names定义为:

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

Is there a difference in what methods these clases define that could explain what you're seeing? 这些条款定义的方法是否存在差异,可以解释您所看到的内容?

The short answer: 简短的回答:

In my case, I was accidentally sending my PATCH to the list URL, rather than the put/patch URL. 在我的情况下,我不小心将我的PATCH发送到list URL,而不是put/patch URL。


The longer answer: 答案越长:

I found that the problem isn't that one project has different defaults for allowed_methods , it's that the action_map and allowed_methods properties of the ViewSet change based on which of the ViewSet URLs you hit, since the action_map is influenced by the router (see SimpleRouter.routes ). 我发现问题不在于一个项目对allowed_methods有不同的默认值,而是action_mapallowed_methods属性会根据您点击的ViewSet URL而发生变化,因为action_map受路由器的影响(请参阅SimpleRouter.routes )。

So if you try to hit "//[base_url]/your-model/" with PATCH or PUT , as I was doing, it will say that only ['GET', 'POST', 'HEAD', 'OPTIONS'] are allowed, and patch() will NOT be linked to partial_update() , even though it uses the same ViewSet class and partial_update() is present in that class. 因此,如果您尝试使用PATCHPUT命中“// [base_url] / your-model /”,就像我一样,它会说只有['GET', 'POST', 'HEAD', 'OPTIONS']允许,并且patch()不会链接到partial_update() ,即使它使用相同的ViewSet类并且该类中存在partial_update()

If you want to send a PATCH , you have to send it to "//[base_url]/your-model/[some_id]/". 如果要发送PATCH ,则必须将其发送到“// [base_url] / your-model / [some_id] /”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM