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.WSGIRequest
drf的Request
	rest_framework.request.Request

drf的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请求提交的数据(查询参数)
posted @ 2021-04-30 08:52  最冷不过冬夜  阅读(52)  评论(0编辑  收藏  举报