<p><strong>这是因为<code>APIView</code>没有为<code>.put()</code>方法定义处理程序,因此传入的请求无法映射到视图上的处理程序方法,从而引发异常。</strong></p>
<p>(注:<code>viewsets.ViewSet</code>继承自<code>ViewSetMixin</code>和<code>APIView</code>)</p>
<p><code>APIView</code>中的<code>dispatch()</code>方法检查是否为请求<code>method</code>定义了方法处理程序。如果<code>dispatch()</code>方法找到请求方法的处理程序,则返回相应的响应。否则,它会引发异常<a href="http://www.django-rest-framework.org/api-guide/exceptions/#methodnotallowed" rel="nofollow">^{<cd10>}</a>。</p>
<p>根据<code>APIView</code>类中<code>dispatch()</code>方法的源代码:</p>
<pre><code>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
</code></pre>
<p>由于视图中未定义<code>.put()</code>方法处理程序,因此DRF调用回退处理程序<code>.http_method_not_allowed</code>。这会引发<code>MethodNotAllowed</code>异常。</p>
<p><code>.http_method_not_allowed()</code>的源代码是:</p>
<pre><code>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
</code></pre>
<p><strong>当您在视图中定义<code>.put()</code>时,它为什么工作?</strong></p>
<p>在视图中定义<code>def put(self, request):</code>时,DRF可以将传入的请求方法映射到视图上的处理程序方法。这导致返回适当的响应,而没有引发异常。</p>