美文网首页
Django REST framework(三): DRF的请

Django REST framework(三): DRF的请

作者: 是立品啊 | 来源:发表于2020-07-12 22:58 被阅读0次

请求模块的入口函数

上节分析到,DRF的请求生命周期的入口其实在APIViewdispatch()中,请求模块的函数入口也是在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作为drfrequest对象的_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

总结

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

相关文章

网友评论

      本文标题:Django REST framework(三): DRF的请

      本文链接:https://www.haomeiwen.com/subject/xitocktx.html