APIView源码分析与序列化器

Django cbv的执行流程

path(‘test/‘,views.TestView.as_view()),# path(‘test/‘,View类的as_view内部有个view闭包函数内存地址),# path的第二个参数是:View类的as_view内部有个view闭包函数内存地址 1 一旦有请求来了,匹配test路径成功 2 执行第二个参数view函数内存地址(requset) 3 本质执行了self.dispatch(request) 4 通过反射去获得方法(如果是get请求,就是get方法) if request.method.lower() in self.http_method_names: handler = getattr(self, request.method.lower(), self.http_method_not_allowed) 5 执行get方法,传入参数 handler(request, *args, **kwargs)

drf APIView的执行流程

path(‘test/‘,APIView类的as_view内部是用了View的as_view内的view闭包函数),# path的第二个参数是:APIView类的as_view内部是用了View的as_view内的view闭包函数 view = super().as_view(**initkwargs) 1 一旦有请求来了,匹配test路径成功 2 执行第二个参数view函数内存地址(requset),还是执行View的as_view内的view闭包函数, 3 执行self.dispatch(request) ---> APIView类的 def dispatch(self, request, *args, **kwargs): # 以后所有的request对象,都是新的request对象,它是drf的Request类的对象 request = self.initialize_request(request, *args, **kwargs) self.request = request try: #整个drf的执行流程内的权限,频率,认证 self.initial(request, *args, **kwargs) 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) return self.response 4 加了个csrf_exempt装饰器。所以,继承了APIView的所有接口,都没有csrf的校验了 return csrf_exempt(view) # 重点 1 所有的csrf都不校验了 2 request对象变成了新的request对象,drf的request对象 3 执行了权限,频率,认证 4 捕获了全局异常(统一处理异常) 5 处理了response对象,浏览器访问是一个样,postman访问又一个样 6 以后,在视图类中使用的request对象已经不是原来的request对象了,现在都是drf的request对象了

Request对象分析

django原生的Request django.core.handlers.wsgi.WSGIRequestdrf的Request rest_framework.request.Requestdrf的request对象内有原生的request request._request:原生的request 在视图类中使用 request.method 拿到的就是请求方式, # 正常拿,应该request._request.method # 如何实现这种操作? 对象.属性会触发类的__getattr__方法 drf的Request类重写了__getattr__ def __getattr__(self, attr): try: # 去原生的request反射属性 return getattr(self._request, attr) except AttributeError: return self.__getattribute__(attr) 虽然视图类中request对象变成了drf的request,但是用起来,跟原来的一样,只不过它多了一些属性 request.data # post请求提交的数据,不论什么格式,都在它中 requst.query_params # get请求提交的数据(查询参数) ### 重点 -drf的request对象用起来跟原来一样(重写了__getattr__) -request.data #post请求提交的数据,不论什么格式,都在它中 -requst.query_params # get请求提交的数据(查询参数)

相关文章