这是因为APIView 没有为.put() 方法定义处理程序,因此传入的请求无法映射到视图上的处理程序方法,从而引发异常。
(注:viewsets.ViewSet 继承自 ViewSetMixin 和 APIView)
APIView 中的dispatch() 方法检查是否为请求method 定义了方法处理程序。如果dispatch() 方法找到请求方法的处理程序,它会返回适当的响应。否则,它会引发异常MethodNotAllowed。
根据APIView类中dispatch()方法的源码:
def dispatch(self, request, *args, **kwargs):
...
...
try:
self.initial(request, *args, **kwargs)
# Get the appropriate handler method
if request.method.lower() in self.http_method_names:
# here handler is fetched for the request method
# `http_method_not_allowed` handler is assigned if no handler was found
handler = getattr(self, request.method.lower(),
self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
response = handler(request, *args, **kwargs) # handler is called here
except Exception as exc:
response = self.handle_exception(exc)
self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response
由于.put() 方法处理程序未在您的视图中定义,DRF 调用回退处理程序.http_method_not_allowed。这会引发 MethodNotAllowed 异常。
.http_method_not_allowed()的源码为:
def http_method_not_allowed(self, request, *args, **kwargs):
"""
If `request.method` does not correspond to a handler method,
determine what kind of exception to raise.
"""
raise exceptions.MethodNotAllowed(request.method) # raise an exception
为什么在您的视图中定义 .put() 时它会起作用?
当您在视图中定义def put(self, request): 时,DRF 可以将传入的请求方法映射到视图上的处理程序方法。这导致返回适当的响应而不会引发异常。