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请求提交的数据(查询参数)
APIView源码分析与序列化器