解析器分类:

  1. JSONPaser ----> 解析 JSON-serialized data (解析JSON序列化的数据)

  2.FormParser ---->解析form 表单中 urlencoded格式数据(application/x-ww-form-urlencoded)

  3.MartiPartParser---->解析 form 表单中 form-data 格式数据(Multipart/form-data)

  4.FileUploadParser---> 解析 '*/*',(Parser for file upload data.)

源码中的解析器

  • 展开源码你会发现,每个解析器下面都会定义一个 解析方法(这是一种面向对象的鸭子类型的体现)。

  • 前端传过的数据以及文件,在后端被使用的时候(request.data,request.FILES)时候解析器才执行解析。所以解析器执行的入口是 request.data or request.FILES

源码部分:

# Request-->_parse() 方法
def _parse(self):
"""
Parse the request content, returning a two-tuple of (data, files) May raise an `UnsupportedMediaType`, or `ParseError` exception.
"""
# 获取文本类型
media_type = self.content_type
try:
# 获取 请求body体中的内容
stream = self.stream
except RawPostDataException:
if not hasattr(self._request, '_post'):
raise
# If request.POST has been accessed in middleware, and a method='POST'
# request was made with 'multipart/form-data', then the request stream
# will already have been exhausted.
if self._supports_form_parsing():
return (self._request.POST, self._request.FILES)
stream = None if stream is None or media_type is None:
if media_type and is_form_media_type(media_type):
empty_data = QueryDict('', encoding=self._request._encoding)
else:
empty_data = {}
empty_files = MultiValueDict()
return (empty_data, empty_files)
# 选择 解析器 返回解析器对象
parser = self.negotiator.select_parser(self, self.parsers)
# 如果没有解析器就报错
if not parser:
raise exceptions.UnsupportedMediaType(media_type) try:
# parser 是已选择的解析器对象(有 JSONparser,Formparser,MultiPartParser,FileUploadParser 是种 ,每个对象里都有一个 parse 方法,用于解析数据或文件。(这里是一种面向对象的鸭子类型的体现))
# 返回解析完的parsed对象
parsed = parser.parse(stream, media_type, self.parser_context)
except Exception:
# If we get an exception during parsing, fill in empty data and
# re-raise. Ensures we don't simply repeat the error when
# attempting to render the browsable renderer response, or when
# logging the request or similar.
self._data = QueryDict('', encoding=self._request._encoding)
self._files = MultiValueDict()
self._full_data = self._data
raise # Parser classes may return the raw data, or a
# DataAndFiles object. Unpack the result as required.
try:
# 最终返回 parsed对象的数据和文件
return (parsed.data, parsed.files)
except AttributeError:
empty_files = MultiValueDict()
return (parsed, empty_files)

  

执行流程(以JSON 格式数据为例)

"""
-->1.request.data
-->2.执行request.data 中的 self._load_data_and_files()
-->3.执行self._load_data_and_files() 中的 self._data, self._files = self._parse()
-->4. 执行self._parse()
-->4.1.执行stream = self.stream-->self._load_stream() 获取请求内容
-->4.2 执行parser = self.negotiator.select_parser(self, self.parsers)获取解析器
-->4.2.1 执行 self.negotiator = negotiator or self._default_negotiator()
--> 如果没有传 就去 配置文件中找api_settings.DEFAULT_CONTENT_NEGOTIATION_CLASS()
-->4.3 执行 parsed = parser.parse(stream, media_type, self.parser_context) 返回通过不同解析器解析出来的被解析对象
-->4.4 返回
"""

Django 之 restframework 解析器源码分析的更多相关文章

  1. django的RestFramework模块的源码分析

    一.APIView源码分析 查看源码的前提要知道,找函数方法必须先在自己的类中找,没有再往父类找,一层一层网上找,不能直接按ctrl点击 在我们自己定义的类中没有as_view方法的函数,所以肯定是继 ...

  2. 一步步实现windows版ijkplayer系列文章之二——Ijkplayer播放器源码分析之音视频输出——视频篇

    一步步实现windows版ijkplayer系列文章之一--Windows10平台编译ffmpeg 4.0.2,生成ffplay 一步步实现windows版ijkplayer系列文章之二--Ijkpl ...

  3. Django的settings文件部分源码分析

    Django的settings文件部分源码分析 在编写Django项目的过程中, 其中一个非常强大的功能就是我们可以在settings文件配置许多选项来完成我们预期的功能, 并且这些配置还必须大写, ...

  4. DRF框架(一)——restful接口规范、基于规范下使用原生django接口查询和增加、原生Django CBV请求生命周期源码分析、drf请求生命周期源码分析、请求模块request、渲染模块render

    DRF框架    全称:django-rest framework 知识点 1.接口:什么是接口.restful接口规范 2.CBV生命周期源码 - 基于restful规范下的CBV接口 3.请求组件 ...

  5. Python解析器源码加密系列之(二):一次使用标准c的FILE*访问内存块的尝试

    摘要:由于近期打算修改Python解释器以实现pyc文件的加密/解密,出于保密的要求,解密之后的数据只能放在内存中,不能写入到文件中.但是后续的解析pyc文件的代码又只能接受FILE*作为入参,所以就 ...

  6. linux调度器源码分析 - 运行(四)

    本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 引言 之前的文章已经将调度器的数据结构.初始化.加入进程都进行了分析,这篇文章将主要说明调度器是如何在程序稳定运 ...

  7. linux调度器源码分析 - 初始化(二)

    本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 引言 上期文章linux调度器源码分析 - 概述(一)已经把调度器相关的数据结构介绍了一遍,本篇着重通过代码说明 ...

  8. 一步步实现windows版ijkplayer系列文章之三——Ijkplayer播放器源码分析之音视频输出——音频篇

    一步步实现windows版ijkplayer系列文章之一--Windows10平台编译ffmpeg 4.0.2,生成ffplay 一步步实现windows版ijkplayer系列文章之二--Ijkpl ...

  9. Linux 内核调度器源码分析 - 初始化

    导语 上篇系列文 混部之殇-论云原生资源隔离技术之CPU隔离(一) 介绍了云原生混部场景中CPU资源隔离核心技术:内核调度器,本系列文章<Linux内核调度器源码分析>将从源码的角度剖析内 ...

随机推荐

  1. mac 下使用nasm

    #安装nasm brew install nasm #创建文件 vi hello.asm 写入如下内容 msg: db "hello world!", 0x0a len: equ ...

  2. GPG实践

    遇见的问题 安装之后没有显示如教程中的 直接提示真实姓名于电子邮件的地址 公钥与密钥 设置吊销证书

  3. SVN版本管理系统使用教程

    1.下载SVN安装包 https://tortoisesvn.net/downloads.html 2.下载SVN汉化包 网页下翻到下载处 3.下载服务端 https://www.visualsvn. ...

  4. Python【每日一问】24

    问: [基础题1]: 请解释一下 if __name__ == '__main__' :的作用 [基础题2]:请输入星期几的第一个字母来判断一下是星期几,如果第一个字母一样,则继续判断第二个字母. P ...

  5. Linux之三剑客

    LINUX之三剑客 本篇主要介绍linux下常用的增删改查工具: grep sed awk grep是linux下一个强大的搜索工具,几乎操作linux的用户每天都会或多或少的用到grep命令,单一个 ...

  6. Web Api 实现删除功能接口

    删除数据 [HttpDelete] public ResultModel DeleteDataById(int id) { var result = new ResultModel(); //实例化数 ...

  7. docker compose 编排

    Compose是Docker的服务编排工具,主要用来构建基于Docker的复杂应用,Compose 通过一个配置文件来管理多个Docker容器,非常适合组合使用多个容器进行开发的场景. 说明:Comp ...

  8. FLASK-SQLALCHEMY如何使用or和and条件进行组合查询

    FLASK-SQLALCHEMY如何使用or和and条件进行组合查询 http://www.cherishlau.site/2018/03/29/flask-sqlalchemy-use-or-and ...

  9. excel 使用

    列于列拼接

  10. Codeforces Round #557 (Div. 1) 简要题解

    Codeforces Round #557 (Div. 1) 简要题解 codeforces A. Hide and Seek 枚举起始位置\(a\),如果\(a\)未在序列中出现,则对答案有\(2\ ...