APIView的as_view简单解读
APIView的as_view 在APIView中as_view本质还是调用了父类的as_view(View的as_view)
@classmethod 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属性是否存在, 存在的话将一个异常信息保存在类中 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(django.views.View) view = super(APIView, cls).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)
APIView的dispatch as_view中调用dispatch -----》这个dispatch是APIView的dispatch
# Note: Views are made CSRF exempt from within `as_view` as to prevent # accidental removal of this exemption in cases where `dispatch` needs to # be overridden. 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. """
# 将args与kwargs保存在对象中, 并将传入的args与kwargs传入initialize_request函数中 self.args = args self.kwargs = kwargs
# 返回的是一个Request对象,对request封装, 以后使用的request都是封装之后的request, 原生的request在request._request中 request = self.initialize_request(request, *args, **kwargs)
# 将request保存在对象中 self.request = request
# 不知道有啥用, 该函数没用到 self.headers = self.default_response_headers # deprecate? try:
# self.initial(request, *args, **kwargs) # Get the appropriate handler method
# 与django.views.View中的一样 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
APIView中initialize_request
def initialize_request(self, request, *args, **kwargs): """ Returns the initial request object. """ parser_context = self.get_parser_context(request)
# 将request封装,并返回该对象 return Request( request, parsers=self.get_parsers(), authenticators=self.get_authenticators(), negotiator=self.get_content_negotiator(), parser_context=parser_context )
APIView中的inititial
def initial(self, request, *args, **kwargs): """ Runs anything that needs to occur prior to calling the method handler. """
# 判断是否设置了FORMAT_SUFFIX_KWARG, 设置了就将它保存, 没设置则为空 self.format_kwarg = self.get_format_suffix(**kwargs)
# 分页相关,暂不看 # Perform content negotiation and store the accepted info on the request neg = self.perform_content_negotiation(request) request.accepted_renderer, request.accepted_media_type = neg
# 版本相关, 暂不看 # Determine the API version, if versioning is in use. version, scheme = self.determine_version(request, *args, **kwargs) request.version, request.versioning_scheme = version, scheme # Ensure that the incoming request is permitted
# 认证, 权限, 频率 self.perform_authentication(request) # 认证通过之后再往下走 self.check_permissions(request) # 查看你有没有权限 self.check_throttles(request) # 进入的次数
Request类:
-1 原生的request是self._request
-2 取以post形式提交的数据,从request.data中取(urlencoded,formdata,json格式)
-3 query_params 就是原生request的GET的数据
-4 上传的文件是从FILES中取
-5 其他的属性,直接request.属性名(因为重写了__getattr__方法)

浙公网安备 33010602011771号