def as_view(cls, **initkwargs):
""" Store the original class on the view function. This allows us to discover information about the view when we do URL reverse lookups. Used for breadcrumb generation. """ # 判断 queryset 是否是 QuerySet 对象 if isinstance(getattr(cls, 'queryset', None), models.query.QuerySet): def force_evaluation(): raise RuntimeError( 'Do not evaluate the `.queryset` attribute directly, ' 'as the result will be cached and reused between requests. ' 'Use `.all()` or call `.get_queryset()` instead.' ) cls.queryset._fetch_all = force_evaluation # 调用父类的 as_view 办法 view = super().as_view(**initkwargs) view.cls = cls view.initkwargs = initkwargs # Note: session based authentication is explicitly CSRF validated, # all other authentication is CSRF exempt. # 禁用了 csrf 认证 return csrf_exempt(view)
通过这行代码 view = super().as_view(**initkwargs) ,能够晓得 APIView 的 as_view 办法也调用了父类 View 的 as_view 办法,源码如下 :
def as_view(cls, **initkwargs):
"""Main entry point for a request-response process.""" for key in initkwargs: if key in cls.http_method_names: raise TypeError("You www.sangpi.comtried to pass in the %s method name as a " "keyword argument to %s(). Don't do that." % (key, cls.__name__)) if not hasattr(cls, key): raise TypeError("%s() received an invalid keyword %r. as_view " "only accepts arguments that are already " "attributes of the class." % (cls.__name__, key)) def view(request, *args, **kwargs): self = cls(**initkwargs) # 如果有 get 游戏属性,外汇跟单gendan5.com没有 head 属性,那么 head 就是 get if hasattr(self, 'get') and not hasattr(self, 'head'): self.head = self.get # 初始化所有视图办法共享的属性 self.setup(request, *args, **kwargs) # 如果没有 request 属性,报异样 if not hasattr(self, 'request'): raise AttributeError( "%s instance has no 'request' attribute. Did you override " "setup() and forget to call super()?" % cls.__name__ ) # 返回一个 `dispatch` 办法 return self.dispatch(request, *args, **kwargs) view.view_class = cls view.view_initkwargs = initkwargs # take name and docstring from class update_wrapper(view, cls, updated=()) # and possible attributes set by decorators # like csrf_exempt from dispatch update_wrapper(view, cls.dispatch, assigned=()) return view
as_view 办法返回的是 view , view 返回的是 dispatch 办法, dispatch 办法也是调用的 APIView 下的 dispatch 办法,游戏源码如下:
def dispatch(self, request, args, *kwargs):
""" `.dispatch()` is pretty much the same as Django's regular dispatch, but with extra hooks for startup, finalize, and exception handling. """ self.args = args self.kwargs = kwargs # 初始化申请,返回的是 Request 对象 request = self.initialize_request(request, *args, **kwargs) self.request = request self.headers = self.default_response_headers # deprecate? try: # 在调用办法处理程序之前运行任何须要产生的操作 self.initial(request, *args, **kwargs) # Get the appropriate handler method # 获取 request 的申请办法 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) # 返回一个 response 响应对象 self.response = self.finalize_response(request, response, *args, **kwargs) return self.response