django中APIView里的dispatch和as_view方法分析

打印 上一主题 下一主题

主题 641|帖子 641|积分 1923

位置:
from rest_framework.views import APIView
继承APIView类视图形式的路由:
  1. path('booksapiview/', views.BooksAPIView.as_view()),  #在这个地方应该写个函数内存地址
复制代码
继承APIView类的视图函数:
  1. from rest_framework.views import APIView
  2. class BooksAPIView(APIView):
  3.     def get(self):
  4.         pass
  5.    
  6.     def post(self):
  7.         pass
复制代码
APIView源码分析:
继承了APIView的视图函数,最终执行的是APIView里的as_view方法
  1. @classmethod
  2. def as_view(cls, **initkwargs):
  3.     """
  4.     Store the original class on the view function.
  5.     This allows us to discover information about the view when we do URL
  6.     reverse lookups.  Used for breadcrumb generation.
  7.     """
  8.     if isinstance(getattr(cls, 'queryset', None), models.query.QuerySet):
  9.         def force_evaluation():
  10.             raise RuntimeError(
  11.                 'Do not evaluate the `.queryset` attribute directly, '
  12.                 'as the result will be cached and reused between requests. '
  13.                 'Use `.all()` or call `.get_queryset()` instead.'
  14.             )
  15.         cls.queryset._fetch_all = force_evaluation
  16.     # 1.调用APIView父类,也就是View类中的as_view方法,将其返回值view在赋值给view
  17.     view = super().as_view(**initkwargs)
  18.     # 2.这里践行了一切皆对象的原则,将cls这个视图类给了view.cls,下面哪个也是一样
  19.     view.cls = cls
  20.     view.initkwargs = initkwargs
  21.     # Note: session based authentication is explicitly CSRF validated,
  22.     # all other authentication is CSRF exempt.
  23.     # 3.这句话的意思就是以后所有继承APIView的试图函数都没有csrf认证了,和View类一样,APIview类的as_view方法最后也返回了view
  24.     # 只不过apiview新增了去除csrf认证这里
  25.     return csrf_exempt(view)
复制代码
注意:上述返回的view内存地址,需要去找dispatch方法是先去apiview里找,而不是view类中的dispatch了
apiview里的dispatch方法分析:
  1. def dispatch(self, request, *args, **kwargs):
  2.     """
  3.     `.dispatch()` is pretty much the same as Django's regular dispatch,
  4.     but with extra hooks for startup, finalize, and exception handling.
  5.     """
  6.     self.args = args
  7.     self.kwargs = kwargs
  8.     # 这里的request是self.initialize_request这个方法返回的新的由rest_framework中的Request类实例化产生的request对象
  9.     request = self.initialize_request(request, *args, **kwargs)
  10.     # 又把新的request对象给了视图函数中的request,从此,视图函数中的request就是新的request对象了
  11.     self.request = request
  12.     self.headers = self.default_response_headers  # deprecate?
  13.     try:
  14.         # 这里执行了apiview里的initial方法,这个方法里面包含了三大认证模块(重要)
  15.         self.initial(request, *args, **kwargs)
  16.         # Get the appropriate handler method
  17.         # 三大认证过了之后,继续走,这里和view里面差不多,通过反射得到对应请求方式的函数地址
  18.         if request.method.lower() in self.http_method_names:
  19.             handler = getattr(self, request.method.lower(),
  20.                               self.http_method_not_allowed)
  21.         else:
  22.             handler = self.http_method_not_allowed
  23.         # 将get请求或者其他请求方式执行之后的结果在给response模块
  24.         response = handler(request, *args, **kwargs)
  25.     # 这里是三大认证出异常的异常模块
  26.     except Exception as exc:
  27.         response = self.handle_exception(exc)
  28.     # 渲染模块,对response这个相应结果在进行包装(就是在前端看到的由rest_framework渲染出来的数据结果页面)
  29.     self.response = self.finalize_response(request, response, *args, **kwargs)
  30.     # 返回该渲染模块
  31.     return self.response
  32. def initial(self, request, *args, **kwargs):
  33.     # 该方法最重要的就是下面三句代码
  34.     # Ensure that the incoming request is permitted
  35.     # 这个是认证组件
  36.     self.perform_authentication(request)
  37.     # 这个是权限组件
  38.     self.check_permissions(request)
  39.     # 这个是频率组件
  40.     self.check_throttles(request)
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

钜形不锈钢水箱

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表