DRF--解析器Parsers

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 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',
    ),
}

相关文章
|
数据库 Python
django drf 实现只有超级用户才能注册账号(涉及自定义权限permissions,获取token信息解析token信息)
django drf 实现只有超级用户才能注册账号(涉及自定义权限permissions,获取token信息解析token信息)
|
索引 数据格式 XML
Solr所有的查询解析器Query Parsers(转:http://blog.csdn.net/jiangchao858/article/details/53859731)
摘要: Solr除了支持常见的解析器之外,还有一些特殊用途的解析器,为了便于之后查阅,总结一下。本文整理自Solr官方文档。 解析器 说明 Standard Query Parser Solr的标准查询解析器Standard Query Parser DisMax Query Parser Solr的查询解析器DisMax Query Parser Extended DisM
1662 0
|
29天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
67 2
|
2月前
|
缓存 Java 程序员
Map - LinkedHashSet&Map源码解析
Map - LinkedHashSet&Map源码解析
75 0
|
2月前
|
算法 Java 容器
Map - HashSet & HashMap 源码解析
Map - HashSet & HashMap 源码解析
57 0
|
2月前
|
存储 Java C++
Collection-PriorityQueue源码解析
Collection-PriorityQueue源码解析
64 0
|
2月前
|
安全 Java 程序员
Collection-Stack&Queue源码解析
Collection-Stack&Queue源码解析
85 0
|
13天前
|
PyTorch Shell API
Ascend Extension for PyTorch的源码解析
本文介绍了Ascend对PyTorch代码的适配过程,包括源码下载、编译步骤及常见问题,详细解析了torch-npu编译后的文件结构和三种实现昇腾NPU算子调用的方式:通过torch的register方式、定义算子方式和API重定向映射方式。这对于开发者理解和使用Ascend平台上的PyTorch具有重要指导意义。
|
17天前
|
缓存 监控 Java
Java线程池提交任务流程底层源码与源码解析
【11月更文挑战第30天】嘿,各位技术爱好者们,今天咱们来聊聊Java线程池提交任务的底层源码与源码解析。作为一个资深的Java开发者,我相信你一定对线程池并不陌生。线程池作为并发编程中的一大利器,其重要性不言而喻。今天,我将以对话的方式,带你一步步深入线程池的奥秘,从概述到功能点,再到背景和业务点,最后到底层原理和示例,让你对线程池有一个全新的认识。
47 12
|
1月前
|
存储 安全 Linux
Golang的GMP调度模型与源码解析
【11月更文挑战第11天】GMP 调度模型是 Go 语言运行时系统的核心部分,用于高效管理和调度大量协程(goroutine)。它通过少量的操作系统线程(M)和逻辑处理器(P)来调度大量的轻量级协程(G),从而实现高性能的并发处理。GMP 模型通过本地队列和全局队列来减少锁竞争,提高调度效率。在 Go 源码中,`runtime.h` 文件定义了关键数据结构,`schedule()` 和 `findrunnable()` 函数实现了核心调度逻辑。通过深入研究 GMP 模型,可以更好地理解 Go 语言的并发机制。

推荐镜像

更多