请求模块分析

Request请求分析

在APIView的dispatch方法中, 调用了request = self.initialize_request(request, *args, **kwargs) 这句话对来自django的request对象进行了二次封装. 它是DRF的自定义Request类. 下面就进行详细的分析.

源码分析

首先跟进initialize_request方法

    def initialize_request(self, request, *args, **kwargs):
        parser_context = self.get_parser_context(request)

        return Request(
            request,                                # django原来的request
            parsers=self.get_parsers(),               # 解析类
            authenticators=self.get_authenticators(),  # 获取认证类
            negotiator=self.get_content_negotiator(),  
            parser_context=parser_context
        )

返回的是Request对象. 继续跟进Request类的定义.

    def __init__(self, request, parsers=None, authenticators=None,
                 negotiator=None, parser_context=None):
        # 下面最重要的就是把原来的request对象封装成了自己的一个保护属性_request
        self._request = request
        self.parsers = parsers or ()
        self.authenticators = authenticators or ()
        self.negotiator = negotiator or self._default_negotiator()
        self.parser_context = parser_context
        self._data = Empty
        self._files = Empty
        self._full_data = Empty
        self._content_type = Empty
        self._stream = Empty
    def __getattr__(self, attr):
        try:
            # 访问request不存在的属性, 则会去访问原生django的request对象的属性.
            return getattr(self._request, attr)
        except AttributeError:
            return self.__getattribute__(attr)

上面这个双下getattr方法是能够将APIView的request对象当做原生django的request对象使用的根本原因.

其他重要的方法, 就是封装了data, FILES, query_params属性

data属性封装了前端传来的json格式, urlencoded格式和formdata格式的数据格式, 使用起来比原来方便了许多.

FILES使用和django一样

query_params就是django的request.GET属性

重点总结

# 1) drf 对原生request做了二次封装,request._request就是原生request
# 2) 原生request对象的属性和方法都可以被drf的request对象直接访问(兼容)
# 3) drf请求的所有url拼接参数均被解析到query_params中,所有数据包数据都被解析到data中

猜你喜欢

转载自www.cnblogs.com/yscl/p/11931104.html
今日推荐