请求模块分析
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中