当前位置: 首页 > news >正文

DRF解析器

1、概念

解析器(Parsers)是 Django REST Framework 中的重要组件,它负责将传入的请求体内容解析为 Python 数据类型。
解析器的作用

  • 解析请求体内容(如 JSON、表单数据、XML 等)
  • 将原始数据转换为 Python 数据结构
  • 使转换后的数据可在 request.data 中访问

解析器工作流程

  1. 客户端发送请求(包含 Content-Type 头)
  2. DRF 根据 Content-Type 选择合适的解析器
  3. 解析器解析请求体内容(首次访问request.data解析)
  4. 视图可以访问和使用这些数据

2、内置解析器

2.1 BaseParser

基类,所有解释器应该继承该类,并制定media_type属性和覆盖parse方法


class BaseParser:media_type = Nonedef parse(self, stream, media_type=None, parser_context=None):raise NotImplementedError(".parse() must be overridden.")

2.1 JSONParser

最常用的解析器,解析 application/json类型的请求体,将 JSON 数据转换为 Python 字典。核心就是json.load


class JSONParser(BaseParser):media_type = 'application/json'renderer_class = renderers.JSONRendererstrict = api_settings.STRICT_JSONdef parse(self, stream, media_type=None, parser_context=None):# ...return json.load(decoded_stream, parse_constant=parse_constant)

2.2 FormParser

解析 application/x-www-form-urlencoded类型的请求体(典型的 HTML 表单数据),返回 QueryDict 对象


class FormParser(BaseParser):media_type = 'application/x-www-form-urlencoded'def parse(self, stream, media_type=None, parser_context=None):parser_context = parser_context or {}encoding = parser_context.get('encoding', settings.DEFAULT_CHARSET)return QueryDict(stream.read(), encoding=encoding)

2.3 FileUploadParser

FileUploadParser用于将整个请求体内容视为一个单一的文件进行解析。它通常用于API接口,客户端直接将文件内容作为请求体发送,而不使用 multipart/form-data格式。

请求示例

curl -X PUT \http://your-api-domain/upload/sample.jpg \  # 文件名可作为URL的一部分-H 'Content-Type: image/jpeg' \             # 设置文件的实际MIME类型--data-binary '@/path/to/your/file.jpg'

视图代码实现


# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.parsers import FileUploadParser
from rest_framework import statusclass SimpleFileUploadView(APIView):# 使用 FileUploadParserparser_classes = [FileUploadParser]def put(self, request, filename, *args, **kwargs): # 注意这里常用 PUT 方法# 整个请求体被解析为一个文件对象,可通过 request.data 获取uploaded_file = request.data# 检查是否有文件数据if not uploaded_file:return Response({"error": "No file content"}, status=status.HTTP_400_BAD_REQUEST)# 通常文件名可以从URL参数或请求头中获取,这里假设从URL捕获# 处理文件,例如保存with open(filename, 'wb+') as destination:for chunk in uploaded_file.chunks():destination.write(chunk)return Response({"message": "File uploaded successfully as single content","filename": filename,"size": uploaded_file.size}, status=status.HTTP_201_CREATED)

2.4 MultiPartParser

用于解析 multipart/form-data类型的请求内容,这是浏览器通过表单上传文件时使用的编码格式。它能够同时处理普通的表单字段和文件字段。

请求示例


curl -X POST \http://your-api-domain/upload/ \-H 'Content-Type: multipart/form-data' \-F 'username=testuser' \-F 'file=@/path/to/your/file.jpg'

视图实现示例

# views.py
class FileUploadView(APIView):# 指定该视图使用的解析器类parser_classes = [MultiPartParser]def post(self, request, *args, **kwargs):# request.data 是一个类似字典的对象,包含所有解析后的表单数据和文件# 获取名为 'file' 的文件对象uploaded_file = request.data.get('file')# 获取名为 'username' 的普通文本字段username = request.data.get('username')if not uploaded_file:return Response({"error": "No file provided"}, status=status.HTTP_400_BAD_REQUEST)# 处理文件,例如保存到磁盘with open(uploaded_file.name, 'wb+') as destination:for chunk in uploaded_file.chunks():destination.write(chunk)# 返回成功响应return Response({"message": "File uploaded successfully","filename": uploaded_file.name,"username": username,"size": uploaded_file.size}, status=status.HTTP_201_CREATED)

3、自定义解释器

创建自定义解析器需要继承 BaseParser 并实现 parse 方法


from rest_framework.parsers import BaseParser
import xml.etree.ElementTree as ETclass XMLParser(BaseParser):"""自定义 XML 解析器"""media_type = 'application/xml'  # 处理的 Content-Typedef parse(self, stream, media_type=None, parser_context=None):"""将 XML 流解析为 Python 字典"""parser_context = parser_context or {}encoding = parser_context.get('encoding', 'utf-8')try:# 读取并解析 XMLxml_text = stream.read().decode(encoding)root = ET.fromstring(xml_text)return self._xml_to_dict(root)except ET.ParseError as e:from rest_framework.exceptions import ParseErrorraise ParseError(f'XML parse error - {e}')def _xml_to_dict(self, element):"""将 XML 元素转换为字典"""result = {}for child in element:if len(child) == 0:result[child.tag] = child.textelse:result[child.tag] = self._xml_to_dict(child)return result

4、配置使用

4.1 全局配置

在 settings.py 中设置默认解析器,默认为JSONParser,FormParser,MultiPartParser

# settings.py
REST_FRAMEWORK = {'DEFAULT_PARSER_CLASSES': ['rest_framework.parsers.JSONParser','rest_framework.parsers.FormParser','rest_framework.parsers.MultiPartParser',],
}

4.2 视图级配置


class FlexibleParserView(APIView):parser_classes = [JSONParser, FormParser, MultiPartParser]def post(self, request):return Response({"data": request.data,"content_type": request.content_type})@api_view(['POST'])
@parser_classes([JSONParser])
def json_only_view(request):return Response({"data": request.data})

5、解析器选择流程

DRF 通过内容协商来选择解析器,也就是根据media_type选择

# rest_framework/request.pyclass Request:def __init__(self, request, parsers=None, authenticators=None, negotiator=None, parser_context=None):self.parsers = parsers or ()@propertydef data(self):if not _hasattr(self, '_full_data'):with wrap_attributeerrors():self._load_data_and_files()return self._full_data      def _load_data_and_files(self):# 只加载一次if not _hasattr(self, '_data'):# 解析数据self._data, self._files = self._parse()def _parse(self):# 获取内容类型media_type = self.content_type#  # 选择解析器parser = self.negotiator.select_parser(self, self.parsers)# 使用选择的解析器进行解析parsed = parser.parse(stream, media_type, self.parser_context)return (parsed.data, parsed.files)
http://www.sczhlp.com/news/52737/

相关文章:

  • redis cluster新增节点
  • 循环访问lua和c#数组的不同之处
  • 网站建站服务公司电话网站多大够用
  • 东莞企业网站推广免费软件安装网站
  • 宣传册设计公司乐至seo
  • 注重网站建设 把好宣传思想关口深圳新恒基建设公司
  • 网站建设专属名词广西住房城乡建设厅官网站
  • vue前端解决跨域
  • lua中处理时区和夏令时
  • 夏令时 - 在无夏令时的时区,isdst参数会被os.time忽略
  • 广州网站seo推广辽宁专业网页设计免费建站
  • 库尔勒网站建设公司网站刷流量有用吗
  • 哪些公司做DZ网站维护杨和勒流网站建设
  • 濮阳住房建设厅网站网站开发 前端 外包
  • 网站建设对我有什么好处演示 又一个wordpress站点
  • 多肉建设网站前的市场分析网站seo分析工具
  • 哪个网站做电子请帖好房屋装修案例
  • 网站flash背景深圳哪家做网站
  • 深圳网站seo推广做问卷赚钱的网站
  • 网站开发工具的是什么用dede做网站去掉版权
  • 建立网站的优势电脑上无法安装wordpress
  • 石家庄市建设厅网站网站正在建设中 蓝色
  • 网站建设方案公司网站制作论文题目
  • 梵美传媒网站是谁做的广州头条新闻最近一周
  • 纯c语言题解
  • pytest.ini 配置教程
  • Anaconda Python管理工具下载及安装步骤(Windows详细教程,新手一看就会)​
  • 8.4.1 算法描述
  • 个人网站建设的目的关键词优化到首页怎么做到的
  • 深圳网站建设前十名怎么利用花生壳做自己的网站