zoukankan      html  css  js  c++  java
  • DRF--解析器Parsers

    前戏

    解析器是干什么的?因为前后端分离,因为可能采用json、xml、html等各种不同格式的内容,后端必须要有一个解析器来解析前端发送过来的数据,也就是翻译器!否则后端凭什么看懂前端的数据?对应地,后端也有一个渲染器Render,和解析器是相反的方向,将后端的数据翻译成前端能明白的数据格式。

    DRF框架提供了许多内置的Parser类,用来处理各种媒体类型的请求,比如json,比如xml。还支持自定义解析器,可以灵活地设计API接受的媒体类型。

    Django原生的解析器对于post的数据,如果要从request.body中解析出来放到request.POST中,那么必须同时满足两个条件:

    • 请求头部 Content_type = 'application/x-www-form-urlencoded'
    • 数据格式必须是: name=xxx&password=xxx&email=xxx.....

    而对于前端发送过来的例如JSON格式的数据则无法处理(当然你自己处理也是可以的)。DRF则不同,它提供了一些额外的解析器帮我们处理各种格式。

    DRF的parsers模块非常简单,只定义了几个解析器类:

    • BaseParser:解析器基类,以下四个类都直接继承它
    • JSONParser
    • FormParser
    • MultiPartParser
    • FileUploadParser

    JSONParser

    解析 JSON 格式的请求内容。其.media_type属性值为  application/json

    FormParser

    解析HTML表单内容,使用QueryDict的数据填充request.data。这也是Django原生支持的解析方式。

    通常我们希望同时支持FormParser和MultiPartParser两种解析器,以便完全支持HTML表单数据。

    .media_type:  application/x-www-form-urlencoded

    MultiPartParser

    解析多部分的HTML表单内容,支持文件上传。

    .media_type:  multipart/form-data

    FileUploadParser

    解析原始文件上传内容。此时, request.data 属性将是一个字典,并且只包含一个键,这个键叫做 'file' ,对应的值包含上传的文件内容。

    如果使用FileUploadParser解析器的视图,在被调用的时候URL中携带一个 filename 关键字参数,则该参数将被用作文件名。如果在没有这个关键字参数的情况下调用它,则客户端必须在HTTP头部的 Content-Disposition 中设置文件名。

    DRF在运行的时候如何知道该使用哪个解析器呢?

    DRF将有效的解析器集定义为类的列表。当  request.data 被访问时,REST框架将检查请求头部的 Content-Type 属性,以此来确定要使用哪个解析器来解析数据。所以,要注意!解析器只有在请求request.data的时候才会被调用!如果不需要data数据,那么就不用解析。

    注意:在开发客户端应用程序时,务必确保在请求头部中包含 Content-Type 属性。如果未设置内容类型,则大多数客户端将默认使用 'application/x-www-form-urlencoded' 类型

    解析器的相关配置参数

    可以在Django项目的settings.py文件中,使用 DEFAULT_PARSER_CLASSES 配置项,进行全局的解析器设置。例如,以下设置仅允许解析JSON格式的请求,而不是默认的JSON或表单数据:

    REST_FRAMEWORK = {
        'DEFAULT_PARSER_CLASSES': (
            'rest_framework.parsers.JSONParser',
        )
    }

    当然,也可以同时支持多种解析器,比如下面的配置,这也是DRF默认的解析器配置:

    REST_FRAMEWORK = {
        'DEFAULT_PARSER_CLASSES': (
            'rest_framework.parsers.JSONParser',
            'rest_framework.parsers.FormParser',
            'rest_framework.parsers.MultiPartParser',
        )
    }

    几种解析器的写法没有先后顺序的要求,不像中间件那样的配置有顺序关系。

    DRF支持视图级别的解析器,比如为基于APIView的类视图专门指定使用的解析器,核心是指定parser_classes 属性为某个解析器:

    from rest_framework.parsers import JSONParser
    from rest_framework.response import Response
    from rest_framework.views import APIView
    
    
    class ExampleView(APIView):
    
        # 配置解析器
        parser_classes = (JSONParser,)
        def post(self, request):
            return Response("Hello World")

    当然,也可以为使用  @api_view 装饰器改造的视图指定专用的解析器,核心是@parser_classes((JSONParser,)) 装饰器:

    from rest_framework.decorators import api_view
    from rest_framework.decorators import parser_classes
    from rest_framework.parsers import JSONParser
    from rest_framework.response import Response
    
    
    @api_view(['POST'])
    @parser_classes((JSONParser,))  # 配置解析器
    def example_view(request):
        return Response({'received data': request.data})

    如果全局配置了解析器,视图里也配置了,则视图里的解析器具有更高的优先级。

    自定义解析器

    要自定义解析器,必须继承 BaseParser 类,设置 .media_type 属性,并实现 .parse(self, stream, media_type, parser_context) 方法,该方法应返回将用于填充 request.data 属性的数据。

    parse()方法的参数说明:

    stream:类似于流的对象,表示请求的主体。

    media_type:请求内容的媒体类型,可选。根据请求头部的 Content-Type: ,这可能比渲染器的 media_type 属性更具体,并且可能包括媒体类型参数。例如 "text/plain; charset=utf-8" 。

    parser_context:可选,字典格式。如果提供,将包含解析请求内容可能需要的任何其他上下文。可选,字典格式。如果提供,将包含解析请求内容可能需要的任何其他上下文。

    下面自定义了一个纯文本解析器,它将字符串形式表示的请求内容,填充到request.data属性。

    from rest_framework.parsers import BaseParser
    
    
    class PlainTextParser(BaseParser):
        """
      纯文本解析器
     """
        media_type = 'text/plain'
        def parse(self, stream, media_type=None, parser_context=None):
            """ 简单的返回一个请求主体内容的字符串形式 """
            return stream.read()

    YAML解析器

    djangorestframework-yaml 包为我们提供了解析和渲染yaml格式的能力。它以前直接包含在REST框架包中,现在作为第三方包出现。

    直接用pip安装

    pip install djangorestframework-yaml 

    可以进行下面的配置:

    REST_FRAMEWORK = {
        'DEFAULT_PARSER_CLASSES': (
            'rest_framework_yaml.parsers.YAMLParser',
             ),
        'DEFAULT_RENDERER_CLASSES': (
            'rest_framework_yaml.renderers.YAMLRenderer',
            ),
    }

    XML解析器

    pip install djangorestframework-xml 

    配置

    REST_FRAMEWORK = {
        'DEFAULT_PARSER_CLASSES': (
            'rest_framework_xml.parsers.XMLParser',
        ),
        'DEFAULT_RENDERER_CLASSES': (
            'rest_framework_xml.renderers.XMLRenderer',
        ),
    }
  • 相关阅读:
    主要工业以太网性能横向比较
    聊一聊工业以太网
    FPGA学习之RoadMap
    我眼中的FPGA
    板级通信总线之SPI及其Verilog实现
    ALTERA FPGA中实现低于时钟周期的端口延时
    Javascript 闭包浅析(一)
    node.js docker centos7 下环境构建命令
    ruby sass 命令
    如何配置nginx的反向代理nodes 3000端口项目
  • 原文地址:https://www.cnblogs.com/zouzou-busy/p/12078097.html
Copyright © 2011-2022 走看看