django_rest_framework
APIView CBV 与路由查找
django路由匹配都是一个路由与一视图函数对应,所以对于cbv写法,最终也是返回与之对应的函数。
当调用as_view()方法时,APIView 将调用父类的 as_view()方法。
def as_view(cls, **initkwargs):
...
view = super().as_view(**initkwargs)
...
父类as_view(),返回内部函数view函数,执行dispatch函数。
def view(request, *args, **kwargs):
...
return self.dispatch(request, *args, **kwargs)
...
return view
dispatch的执行,首先会判断是否请求方法是否合法,然后找到对应方法的属视图函数:
原生的dispatch方法:
def dispatch(self, request, *args, **kwargs):
if request.method.lower() in self.http_method_names:
#http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
#获取对应的视图函数
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs) #执行对应方法的视图函数
rest_framework dispatch方法 ,
现对夫类,开始是添加额外的
对request对象进行功能添加hooks, finalize以及异常的处理
def dispatch(self, request, *args, **kwargs):
self.args = args
self.kwargs = kwargs
request = self.initialize_request(request, *args, **kwargs)
request = Request(
request,
parsers=self.get_parsers(), #DEFAULT_PARSER_CLASSES
authenticators=self.get_authenticators(), #认证相关 DEFAULT_AUTHENTICATION_CLASSES
negotiator=self.get_content_negotiator(),# DEFAULT_CONTENT_NEGOTIATION_CLASS
parser_context=parser_context
)
self.request = request
self.headers = self.default_response_headers # deprecate?
try:
self.initial(request, *args, **kwargs)
# Get the appropriate handler method
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(),
self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
response = handler(request, *args, **kwargs) #视图执行
except Exception as exc:
response = self.handle_exception(exc)
self.response = self.finalize_response(request, response, *args, **kwargs) # 返回最终response对象
return self.response #返回响应