• DRF--请求和响应


    请求

    对于DRF的request对象,有下面的属性:

    • .data
    • .query_params
    • .parsers
    • .accepted_renderer
    • .accepted_media_type
    • .user
    • .auth
    • .authenticators
    • .method
    • .content_type
    • .stream

    REST framework的 Request 类扩展了Django标准的 HttpRequest ,添加了对REST framework请求解析和身份验证的支持。

    源代码

    class Request(object):
      """
     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

    REST framework的request请求对象以通常处理表单数据相同的方式使用JSON数据或其他媒体类型处理请求。下面的属性是request中数据主体的部分。

    .data

    request.data  返回请求正文的解析内容,这与标准的  request.POST  和  request.FILES  属性类似,除了下面的区别:

    • request.data  包含所有解析的内容, 包括 文件或非文件输入。
    • request.data  支持除 POST 之外的HTTP方法,这意味着你可以访问 PUT 和 PATCH 请求的内容。
    • request.data  支持更灵活的请求解析,而不仅仅是表单数据。 例如,你可以与处理表单数据相同的方式处理传入的JSON数据。
    @property
    def data(self):
        if not _hasattr(self, '_full_data'):
          self._load_data_and_files()
        return self._full_data

    .query_params

    request.query_params 是 request.GET 的一个更准确的同义词,也就是在DRF中的替代品。

    为了让你的代码清晰明了, 我们建议使用  request.query_params  而不是Django标准的request.GET 。这样做有助于保持代码库更加正确和明了。通俗地说,就是不要把DRF的属性/方法名和Django原生的属性/方法名混用。

    def query_params(self):
        """
       More semantically correct name for request.GET.
       """
       return self._request.GET

    .parsers

    APIView 类或 @api_view 装饰器将根据view中设置的 parser_classes 值或DEFAULT_PARSER_CLASSES 配置参数进行设置,确保此属性自动设置为 Parser 实例列表。通常并不需要访问这个属性。

    Note: 如果客户端发送格式错误的内容,则访问 request.data 可能会引发 ParseError 。默认情况下REST framework的  APIView 类或 @api_view 装饰器将捕获错误并返回 400 BadRequest 响应。

    如果客户端发送具有无法解析的内容类型(content-type)的请求,则会引发  UnsupportedMediaType  异常, 默认情况下会捕获该异常并返回  415 Unsupported Media Type  响应。

    .user

    request.user  默认情况下使用的是Django自带的auth框架的用户模型,返回一个  django.contrib.auth.models.User  实例。但该行为取决于你所使用的的认证策略,很显然当你使用第三方认证模块时,就不一样了。

    如果请求未认证则  request.user  的默认值为  django.contrib.auth.models.AnonymousUser 的一个实例。

    .method

    request.method  返回请求的HTTP方法的 大写 字符串表示形式。隐含支持基于浏览器的  PUT ,  PATCH  和  DELETE  方法。

    .content_type

    request.content_type  返回HTTP请求正文的媒体类型的字符串对象,如果未提供媒体类型,则返回空字符串。也就是正文的格式。

    一般我们不使用这个属性,但如果真要在DRF中访问请求的内容类型,请务必使用  .content_type  属性,而不是使用  request.META.get('HTTP_CONTENT_TYPE') , 因为前者为基于浏览器的非表单内容提供了隐含的支持。

    响应

    REST framework 提供一个  Response  类来支持 HTTP内容协商,该类允许返回可以呈现为多种类型的内容,具体取决于客户端的请求。

    这个 Response  类是 Django中  SimpleTemplateResponse  类的一个子类。 Response  对象使用Python原生的数据类型进行初始化。 然后REST framework 使用标准的HTTP内容协商来确定如何呈现最终的响应内容。

    我们并不一定非要使用DRF的  Response  类进行响应,也可以返回常规的  HttpResponse  或者  StreamingHttpResponse  对象,但是使用 Response 类可以提供一个多种格式的更漂亮的界面。

    除非由于某种原因你要对 REST framework 做大量的自定义,否则你应该始终使用  APIView  类或者  @api_view 函数这些DRF提供的视图。这样做可以确保视图在返回之前能够执行 内容协商并且为响应选择适当的渲染器。

    Django中的模型中的具体数据内容可以json化,我们需要自己写serializer,也就是序列化器,进行模型model对象的序列化和反序列化。如果不这么做,那前端看着后端发来的数据会懵逼的,后端拿着前端post过来的数据也不知道该怎么存到数据库里去。

    你可以使用 REST framework的  Serializer  类来执行此类数据的序列化,或者使用你自定义的序列化器。

    参数说明:

    .data

    未渲染的,已经序列化的要响应的数据

    .status_code

    HTTP 响应的数字状态码。

    content_type

    响应的内容类型。通常由渲染器自行设置,由协商内容确定,但是在某些情况下,你需要明确指定内容类型。

  • 相关阅读:
    方法的重载理解
    JAVA 三种循环的总结
    模拟时间倒计时
    制作漂浮广告效果
    js+css+html实现抽奖小程序
    将系统时间转换为汉字表示的四种方法
    简单的导航栏
    模仿光标闪烁,光标移动,自动切换背景
    sublime插件emmet安装和使用
    现在有一张半径为r的圆桌,其中心位于(x,y),现在他想把圆桌的中心移到(x1,y1)。每次移动一步,都必须在圆桌边缘固定一个点然后将圆桌绕这个点旋转。问最少需要移动几步。
  • 原文地址:https://www.cnblogs.com/zouzou-busy/p/12061789.html
Copyright © 2020-2023  润新知