APIView源码分析
1.和CBV源码执行流程相似,请求来了先走路由层:
path('books/', views.BookView.as_view())
2.走APIView的as_view方法,代码如下:
@classmethod def as_view(cls, **initkwargs): view = super().as_view(**initkwargs) # 调用父类的 as_view,view还是View的as_view # 以后所有请求,都不会做csrf认证了 return csrf_exempt(view)
——as_view执行结果跟之前CBV的一样,额外去除了csrf认证
3.内部核心执行dispatch方法并传入request,流程示意如下:
1.请求来了执行 views.BookView.as_view()(request) 2.view(request) 3.csrf_exempt(view)(request) # 内部核心 4.return self.dispatch(request)
4.源码分析
def dispatch(self, request, *args, **kwargs): # 后续的request都是 initialize_request 返回结果--》新的request--》drf的Requet类的对象 request = self.initialize_request(request, *args, **kwargs) # 新的request放到了 self.request中---》self是BookView类的对象 # 后续视图类的方法中 可以直接 self.request取出 当次请求的request对象 self.request = request try: # 执行了三大认证: ''' self.perform_authentication(request) self.check_permissions(request) self.check_throttles(request) ''' self.initial(request, *args, **kwargs) # 与CBV相似——通过反射,去视图类中:BookView中执行跟请求方式同名的方法 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 # request是新的Request类的对象了 get方法的第一个参数request也是新的 response = handler(request, *args, **kwargs) ########################执行视图类的方法结束###### except Exception as exc: # 如果在执行三大认证或视图类方法中,出了错,都会被异常捕获,统一处理 response = self.handle_exception(exc) self.response = self.finalize_response(request, response, *args, **kwargs) return self.response
总结:
1 以后视图类方法中得request对象,变成了新的request,rest_framework.request.Request的对象,但是用起来跟之前一样
2 把新的request对象,同时放到了 视图类的对象中self.request = request后续从视图类中可以直接通过self.request取出来
3 在执行视图类的方法之前,执行了三大认证
4 如果三大认证或视图类的方法执行出错,会有全局异常处理
5 以后所有的接口都去除了csrf认证