目录
各种源码分析汇总
本篇文章会总结各种牛逼的方法功能的源码分析,从而更加加深印象、培养自己独立源码分析的能力。本篇分析了CBV源码、APIView源码、Request对象源码···
一、CBV源码分析
1.分析结论
- 当浏览器客户端想服务端发送请求时通过路由匹配到的对应视图函数加括号调用
- 路由对应的必须是一个函数地址因此CBV的本质也是FBV
- as_view也是一个类方法且该方法加括号调用后返回的结果是一个函数内存地址
- as_view方法在父类view中定义的,通过继承才能用
- 运行view方法返回self.dispatch()方法的运行结果
- dispatch方法可以根据不同的请求方式执行视图类中对应的方法
2.分析流程
1 从路由出发
path('api/v1/books/', views.BookView.as_view()),第二个参数无论是fbv还是cbv放的都是函数内存地址
2.当请求来了,匹配成功会执行,views.BookView.as_view()(request)
views.BookView.as_view()执行结果是View的类方法as_view返回的结果是内层函数view,是个函数内层地址
3.本身请求来了,匹配成功,会执行view(request)
def view(request, *args, **kwargs):
return self.dispatch(request, *args, **kwargs)
4.通过self.dispatch View类的方法来引出dispatch方法
def dispatch(self, request, *args, **kwargs):
# request.method请求方式转成小写,必须在列表中才能往下走
if request.method.lower() in self.http_method_names:
# 反射,去self【视图类的对象:BookView】,去通过get字符串,反射出属性或方法
# BookView的get方法
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
# BookView的get方法,加括号,传入request
return handler(request, *args, **kwargs)
二、APIView源码分析
1.分析结论
- 去处了所有的csrf
- 包装了新的request,新的request=request._request
- 在执行视图类的方法之前、执行了3大认证
- 如果3大认证执行过程中出现错会有全局异常捕获
- 以后的视图类方法中的request都是新的了
2.分析流程
1.从路由出发
path('books/', views.BookView.as_view()),
# 请求来了配备到路由就执行第二个参数加括号 这时的as_view是APIView的as_view 这一步以后就没有csrf认证了
2.分析as_view
@classmethod
def as_view(cls, **initkwargs):
# 调用父类的as_view,父类是Django原生的View
# 把Django原生View的as_view方法中的闭包函数view拿出来了
view = super().as_view(**initkwargs)
# csrf_exempt排除所有csrf的认证
# 相当于在所有的方法上面加了这个装饰器
总结一下前半部分:
路由匹配成功
执行csrf_exempt(view)(request)
View的as_view中的闭包函数view
self.dispatch,self是视图类的对象
BookView继承了APIView的dispatch方法
3.分析dispatch方法
def dispatch(self, request, *args, **kwargs):
# 这里的老request
request = self.initialize_request(request, *args, **kwargs)
# 从此以后就是新的request 老的request在request._request里
# 把新的request放到了self对象【BookView的对象】
self.request = request
try:
# 在异常捕获这里执行了三大认证
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
# 把新的request传入了 视图类的方法中get的request也是新的
response = handler(request, *args, **kwargs)
except Exception as exc:
# 执行三大认证过程中出现任何异常都能捕获--->全局异常捕获
response = self.handle_exception(exc)
self.response = slef.finalize_response(request, response, *args. **kwargs)
return self.response
三、Request对象源码分析
1.分析结论
- 新的request用起来跟之前的一样 因为新的获取不到会获取老的
- request.data对编码格式和请求方式没有限制只要是body中的数据都可以取 取出来都是字典
- request.query_params就是原来的request._request.GET
- 上传的文件从request.FILES取
2.分析流程
老的request:django.core.handlers.wsgi.WSGIRequest
新的request:from rest_framework.request import Request
1.从 __getattr__方法入手 在视图类的方法中,执行request.method ,新的request是没有method的,就触发了新的Request的__getattr__方法的执行
def __getattr__(self, attr):
try:
# 从老的request中反射出 要取得属性
return getattr(self._request, attr)
except AttributeError:
return self.__getattribute__(attr)
2.request.data 这个方法包装成了数据属性 以后无论post,put···放在body中提交的数据,都从request.data中取,取出来就是字典 也不限制编码格式
3.request.query_params 这个方法包装成了数据属性 get请求携带的参数,以后从这里面取
query_params:查询参数--->restful规范请求地址中带查询参数
4.request.FILES这个方法包装成了数据属性前端提交过来的文件,从这里取
标签:分析,汇总,self,request,源码,方法,method,view
From: https://www.cnblogs.com/almira998/p/17083476.html