cbv源码分析, APIView执行过程分析 , drf 的 request对象等

CBV源码分析

# 我们在路由中写了 IndexView.as_view()---->实际上放了一个函数内存地址,源码是---》实际上是view的内存地址

  @classonlymethod
  def view(request, *args, **kwargs):
return self.dispatch(request, *args, **kwargs)
return view

# 当请求来了,跟路由匹配成功,就会执行view(request)

# 内部执行了self.dispatch(request, *args, **kwargs)

def dispatch(self, request, *args, **kwargs):

# 'get' in 列表

if request.method.lower() in self.http_method_names:

# 通过反射去对象中拿get方法

# handler就是get这个方法

handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs)

# 最终执行了handler(request, *args, **kwargs)
-如果是get请求,相当于执行了视图类中的get方法

 

 

 

drf中APIview执行过程分析

# 请求来了,会执行views.BookView.as_view()(request)---->触发APIView的as_view
@classmethod
def as_view(cls, **initkwargs):
view = super().as_view(**initkwargs) # 调用了View的as_view
return csrf_exempt(view) # 去掉了csrf的认证,跟原来加装饰器一样
# 假设get请求来了,执行view()--最重要的-->self.dispatch()--》APIView的
def dispatch(self, request, *args, **kwargs):
# 把原来的request对象,包装成了新的request对象,是drf的request
request = self.initialize_request(request, *args, **kwargs)
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
# 真正的执行视图类中的方法,如果有异常,被捕获了
response = handler(request, *args, **kwargs)
except Exception as exc:
response = self.handle_exception(exc)
return self.response


    # 重点:
  apiview:干了三件事
  -把老的request对象包装成了新的request对象
  -通过APIView的initialize_request,包装的
  -以后再在视图类中用的request对象,都是新的
  -在执行视图类中的方法之前,执行了三大认证
  self.perform_authentication(request)
  self.check_permissions(request)
  self.check_throttles(request)
  -处理全局异常


只要继承了APIView,以后用的request对象,就是drf的request对象了
在执行视图类的方法之前,会先执行三大认证,如果有异常,会被捕获并处理

 

drf 中的request对象

# from rest_framework.request import Request
# 重点
-老的django的request在drf的request._request中
-新的request用起来跟原来一模一样用,没有一点区别
-对象.属性,会触发类的 __getattr__方法
-重写了__getattr__
return getattr(self._request, attr)
-新的request多个一个data属性--》所有post提交的数据,都放在它中

 

posted @ 2021-09-01 15:52  草木秋死  阅读(36)  评论(0)    收藏  举报