drf——APIView及其内部函数/类的源码分析

一、知识储备

1 APIview的as_view
    -内部还是执行了View的闭包函数view
    -禁用掉了csrf
    -一切皆对象,函数也是对象  函数地址.name=lili

2 原生View类中过的as_view中的闭包函数view
    -本质执行了self.dispatch(request, *args, **kwargs),执行的是APIView的dispatch

二、APIView的源码分析

# drf:APIView的源码分析

    def as_view(cls, **initkwargs):
        # 这句话执行完成返回 view闭包函数的内存地址
        view = super().as_view(**initkwargs) # 调用父类(View)的as_view
        view.cls = cls
        view.initkwargs = initkwargs
        view=csrf_exempt(view)  # 局部禁用csrf
        return view

 # 装饰器的使用方式
@csrf_exempt   ====>view=csrf_exempt(view)
def view():
    pass

# 请求来了,会执行上面返回的view()---->self.dispatch(APIView的dispatch)

三、APIView的dispatch源码分析

# APIView的dispatch源码分析
    def dispatch(self, request, *args, **kwargs):
     # 把原生的request,封装进新的Request对象(drf的Request)
        # DRF的Request类的对象,内部有request._request,它就是原生request
        request = self.initialize_request(request, *args, **kwargs)
        self.request = request

        try:
            self.initial(request, *args, **kwargs)
            '''
            #认证,权限,频率
            self.perform_authentication(request)
            self.check_permissions(request)
            self.check_throttles(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
       # 这个request新的requst,是drf中Request对象
       # response是原生response
            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

四、Request类分析

Request类
    -request._request:原生request
    -request.data    : post请求提交的数据(urlencoded,json,formdata)
    -request.user    :不是原生的user了
    -request.query_params :原生的request.GET,为了遵循restful规范
    -requset.FILES   :新的
    -重写了__getattr__,新的request.原来所有的属性和方法,都能直接拿到
        def __getattr__(self, attr):
            return getattr(self._request, attr)

 

posted @ 2020-11-04 20:14  1024bits  阅读(191)  评论(0编辑  收藏  举报