parsers.py

解析器

机器交互式 Web 服务倾向于使用比表单编码更具结构化的格式来发送数据,因为它们发送的数据比简单表单更复杂

— Malcom Tredinnick,Django 开发者组

REST 框架包含许多内置解析器类,允许你接受具有各种媒体类型的请求。它还支持定义你自己的自定义解析器,这为你设计 API 接受的媒体类型提供了灵活性。

解析器如何确定

视图的有效解析器集始终定义为一个类列表。当访问 request.data 时,REST 框架将检查传入请求上的 Content-Type 头,并确定使用哪个解析器来解析请求内容。


注意:在开发客户端应用程序时,务必记住在 HTTP 请求中发送数据时设置 Content-Type 头。

如果你不设置内容类型,大多数客户端将默认使用 'application/x-www-form-urlencoded',这可能不是你想要的。

例如,如果你使用 jQuery 和 .ajax() 方法发送 json 编码数据,则应确保包含 contentType: 'application/json' 设置。


设置解析器

可以使用 DEFAULT_PARSER_CLASSES 设置全局设置默认解析器集。例如,以下设置只允许具有 JSON 内容的请求,而不是默认的 JSON 或表单数据。

REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES': [
        'rest_framework.parsers.JSONParser',
    ]
}

你还可以使用基于类的视图 APIView 设置用于单个视图或视图集的解析器。

from rest_framework.parsers import JSONParser
from rest_framework.response import Response
from rest_framework.views import APIView

class ExampleView(APIView):
    """
    A view that can accept POST requests with JSON content.
    """
    parser_classes = [JSONParser]

    def post(self, request, format=None):
        return Response({'received data': request.data})

或者,如果你正在使用基于函数视图的 @api_view 装饰器。

from rest_framework.decorators import api_view
from rest_framework.decorators import parser_classes
from rest_framework.parsers import JSONParser

@api_view(['POST'])
@parser_classes([JSONParser])
def example_view(request, format=None):
    """
    A view that can accept POST requests with JSON content.
    """
    return Response({'received data': request.data})

API 参考

JSONParser

解析 JSON 请求内容。request.data 将填充数据字典。

.media_type: application/json

FormParser

解析 HTML 表单内容。request.data 将填充数据 QueryDict

通常,你希望同时使用 FormParserMultiPartParser 来完全支持 HTML 表单数据。

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

MultiPartParser

解析支持文件上传的多部分 HTML 表单内容。request.datarequest.FILES 将分别填充 QueryDictMultiValueDict

通常,你希望同时使用 FormParserMultiPartParser 来完全支持 HTML 表单数据。

.media_type: multipart/form-data

FileUploadParser

解析原始文件上传内容。request.data 属性将是一个字典,其中包含一个键 'file',包含已上传的文件。

如果与 FileUploadParser 一起使用的视图使用 filename URL 关键字参数调用,则该参数将用作文件名。

如果在没有 filename URL 关键字参数的情况下调用它,则客户端必须在 Content-Disposition HTTP 标头中设置文件名。例如 Content-Disposition: attachment; filename=upload.jpg

.media_type: */*

注释
  • FileUploadParser 用于可以将文件上传为原始数据请求的本机客户端。对于基于 Web 的上传或支持多部分上传的本机客户端,你应该改用 MultiPartParser
  • 由于此解析器的 media_type 匹配任何内容类型,因此 FileUploadParser 通常应该是 API 视图上设置的唯一解析器。
  • FileUploadParser 尊重 Django 的标准 FILE_UPLOAD_HANDLERS 设置和 request.upload_handlers 属性。有关更多详细信息,请参阅 Django 文档
基本用法示例
# views.py
class FileUploadView(views.APIView):
    parser_classes = [FileUploadParser]

    def put(self, request, filename, format=None):
        file_obj = request.data['file']
        # ...
        # do some stuff with uploaded file
        # ...
        return Response(status=204)

# urls.py
urlpatterns = [
    # ...
    re_path(r'^upload/(?P<filename>[^/]+)$', FileUploadView.as_view())
]

自定义解析器

要实现自定义解析器,你应该覆盖 BaseParser,设置 .media_type 属性,并实现 .parse(self, stream, media_type, parser_context) 方法。

该方法应返回将用于填充 request.data 属性的数据。

传递给 .parse() 的参数是

表示请求正文的类流对象。

媒体类型

可选。如果提供,这是传入请求内容的媒体类型。

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

解析器上下文

可选。如果提供,此参数将是一个字典,其中包含解析请求内容可能需要的任何其他上下文。

默认情况下,这将包括以下键:viewrequestargskwargs

示例

以下是一个示例纯文本解析器,它将使用表示请求正文的字符串填充 request.data 属性。

class PlainTextParser(BaseParser):
    """
    Plain text parser.
    """
    media_type = 'text/plain'

    def parse(self, stream, media_type=None, parser_context=None):
        """
        Simply return a string representing the body of the request.
        """
        return stream.read()

第三方包

以下第三方包也可用。

YAML

REST 框架 YAML 提供 YAML 解析和渲染支持。它以前直接包含在 REST 框架包中,现在则作为第三方包提供支持。

安装和配置

使用 pip 安装。

$ pip install djangorestframework-yaml

修改您的 REST 框架设置。

REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES': [
        'rest_framework_yaml.parsers.YAMLParser',
    ],
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework_yaml.renderers.YAMLRenderer',
    ],
}

XML

REST 框架 XML 提供一个简单的非正式 XML 格式。它以前直接包含在 REST 框架包中,现在则作为第三方包提供支持。

安装和配置

使用 pip 安装。

$ pip install djangorestframework-xml

修改您的 REST 框架设置。

REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES': [
        'rest_framework_xml.parsers.XMLParser',
    ],
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework_xml.renderers.XMLRenderer',
    ],
}

MessagePack

MessagePack 是一种快速、高效的二进制序列化格式。 Juan Riaza 维护 djangorestframework-msgpack 包,该包为 REST 框架提供 MessagePack 渲染器和解析器支持。

CamelCase JSON

djangorestframework-camel-case 为 REST 框架提供骆驼式 JSON 渲染器和解析器。这允许序列化程序使用 Python 风格的下划线字段名称,但以 JavaScript 风格的骆驼式字段名称在 API 中公开。它由 Vitaly Babiy 维护。