请求模块的入口函数
上节分析到,DRF的请求生命周期的入口其实在APIView
的dispatch()
中,请求模块的函数入口也是在dispatch()
中
APIView的dispatch的self.initialize_request(request, *args, **kwargs)
源码分析
def initialize_request(self, request, *args, **kwargs):
"""
Returns the initial request object.
"""
parser_context = self.get_parser_context(request)
return Request(
request,
parsers=self.get_parsers(),
authenticators=self.get_authenticators(),
negotiator=self.get_content_negotiator(),
parser_context=parser_context
)
- 获得解析上下文后,就实例化了一个
Request()
对象,并抛给上一层
Request类源码
- REST framework的 Request 类扩展了Django标准的 HttpRequest
- 将原生
request
作为drf
的request
对象的_request
属性,拷贝一份 -
__getattr__(self, attr)()
中 兼容django
原生request
的属性,先去Django
中的HttpRequest
对象中找,找不到再去drf
中找
class Request:
"""
Wrapper allowing to enhance a standard `HttpRequest` instance.
Kwargs:
- request(HttpRequest). The original request instance.
- parsers_classes(list/tuple). The parsers to use for parsing the
request content.
- authentication_classes(list/tuple). The authentications used to try
authenticating the request's user.
"""
def __init__(self, request, parsers=None, authenticators=None,
negotiator=None, parser_context=None):
assert isinstance(request, HttpRequest), (
'The `request` argument must be an instance of '
'`django.http.HttpRequest`, not `{}.{}`.'
.format(request.__class__.__module__, request.__class__.__name__)
)
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
if self.parser_context is None:
self.parser_context = {}
self.parser_context['request'] = self
self.parser_context['encoding'] = request.encoding or settings.DEFAULT_CHARSET
force_user = getattr(request, '_force_auth_user', None)
force_token = getattr(request, '_force_auth_token', None)
if force_user is not None or force_token is not None:
forced_auth = ForcedAuthentication(force_user, force_token)
self.authenticators = (forced_auth,)
def __getattr__(self, attr):
"""
If an attribute does not exist on this instance, then we also attempt
to proxy it to the underlying HttpRequest object.
"""
try:
return getattr(self._request, attr)
except AttributeError:
return self.__getattribute__(attr)
Requets对象的方法和属性
请求解析相关
.data
- 包含所有解析的内容, 包括 文件或非文件输入
query_params
-
request.GET
的一个更准确的同义词,也就是在DRF中的替代
品。查询字符串参数
.parsers
-
APIView
类或@api_view
装饰器将根据view
中设置的parser_classes
值或DEFAULT_PARSER_CLASSES
配置参数进行设置,确保此属性自动设置为 Parser 实例列表。
内容协商相关
.accepted_renderer
- 内容协商阶段选择的renderer实例
.accepted_media_type
- 内容协商阶段接受的媒体类型的字符串
认证相关
.user
.auth
.authenticators
浏览器相关
.method
.content_type
.stream
总结
-
drf
对原生requets
做了二次封装,request._request
就是原生的requets
- 原生的
request
对象属性和方法都可以被drf
的request
对象直接访问(兼容) -
drf
请求的所有URL拼接参数都被解析到rquest.query_params
中,所有数据包数据都被解析到rquest.data
中 -
get
无法提供数据包参数,但是post
可以提供url
拼接参数
网友评论