Django 之 restframework 解析器源码分析
解析器分类:
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 解析器源码分析的更多相关文章
- django的RestFramework模块的源码分析
一.APIView源码分析 查看源码的前提要知道,找函数方法必须先在自己的类中找,没有再往父类找,一层一层网上找,不能直接按ctrl点击 在我们自己定义的类中没有as_view方法的函数,所以肯定是继 ...
- 一步步实现windows版ijkplayer系列文章之二——Ijkplayer播放器源码分析之音视频输出——视频篇
一步步实现windows版ijkplayer系列文章之一--Windows10平台编译ffmpeg 4.0.2,生成ffplay 一步步实现windows版ijkplayer系列文章之二--Ijkpl ...
- Django的settings文件部分源码分析
Django的settings文件部分源码分析 在编写Django项目的过程中, 其中一个非常强大的功能就是我们可以在settings文件配置许多选项来完成我们预期的功能, 并且这些配置还必须大写, ...
- DRF框架(一)——restful接口规范、基于规范下使用原生django接口查询和增加、原生Django CBV请求生命周期源码分析、drf请求生命周期源码分析、请求模块request、渲染模块render
DRF框架 全称:django-rest framework 知识点 1.接口:什么是接口.restful接口规范 2.CBV生命周期源码 - 基于restful规范下的CBV接口 3.请求组件 ...
- Python解析器源码加密系列之(二):一次使用标准c的FILE*访问内存块的尝试
摘要:由于近期打算修改Python解释器以实现pyc文件的加密/解密,出于保密的要求,解密之后的数据只能放在内存中,不能写入到文件中.但是后续的解析pyc文件的代码又只能接受FILE*作为入参,所以就 ...
- linux调度器源码分析 - 运行(四)
本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 引言 之前的文章已经将调度器的数据结构.初始化.加入进程都进行了分析,这篇文章将主要说明调度器是如何在程序稳定运 ...
- linux调度器源码分析 - 初始化(二)
本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 引言 上期文章linux调度器源码分析 - 概述(一)已经把调度器相关的数据结构介绍了一遍,本篇着重通过代码说明 ...
- 一步步实现windows版ijkplayer系列文章之三——Ijkplayer播放器源码分析之音视频输出——音频篇
一步步实现windows版ijkplayer系列文章之一--Windows10平台编译ffmpeg 4.0.2,生成ffplay 一步步实现windows版ijkplayer系列文章之二--Ijkpl ...
- Linux 内核调度器源码分析 - 初始化
导语 上篇系列文 混部之殇-论云原生资源隔离技术之CPU隔离(一) 介绍了云原生混部场景中CPU资源隔离核心技术:内核调度器,本系列文章<Linux内核调度器源码分析>将从源码的角度剖析内 ...
随机推荐
- js中a + 1 < a等于true,(a ==1 && a== 2 && a==3) 等于 true如何实现
先说a + 1 < a const a = { i: 1, valueOf: () => { if (a.i === 1) { return a.i++; } return a.i+2; ...
- QHBoxLayout 、QFormLayout 遍历子部件,查找QLineEdit控件
布局如下: QLineEdit * edit1 = new QLineEdit; QLineEdit * edit2 = new QLineEdit; QLineEdit * edit3 = new ...
- Spring 事物隔离级别,事物传播行为
Spring 框架中对于事物的管理,主要定义了一下四种属性: 事物的隔离(Isolation)级别 事物的传播行为(Propagation Behavior) 事物的超时时间(TImeout) 是否为 ...
- NIO (一) NIO是什么
参考文档:java为什么需要NIO:https://liuchi.coding.me/2017/08/01/浅谈Java为什么需要NIO/美团技术团队 NIO浅析:https://tech.meitu ...
- 提取文件中的每一个mask,并将mask命名为文件名字
import cv2 as cv import random import glob import os from PIL import Image import shutil def get_sam ...
- 《Linux就该这么学》培训笔记_ch12_使用Samba或NFS实现文件共享
<Linux就该这么学>培训笔记_ch12_使用Samba或NFS实现文件共享 文章最后会post上书本的笔记照片. 文章主要内容: SAMBA文件共享服务 配置共享资源 Windows挂 ...
- linux_problem
今日自学遇到两个问题:火狐浏览器显示安全错误,按照国内网站上抄来抄去的解决办法并没有解决我的问题,即,每次访问新的网站都会提示"support mozilla.org 的管理员...&quo ...
- kafka作为elk缓存使用
ELK集群在大规模的日志收集中面临着数据量大,收集不及时,或宕机的风险,可以选择单节点的redis,但是相比redis,kafka集群高可用的特性,更优,下面来配置kafka集群配置elk作为缓存的方 ...
- Jumpserver 5.2版本安装与部署
组件说明 Jumpserver 为管理后台, 管理员可以通过 Web 页面进行资产管理.用户管理.资产授权等操作, 用户可以通过 Web 页面进行资产登录, 文件管理等操作 koko 为 SSH Se ...
- C语言字节对齐分析
1.前言 什么是字节对齐呢?现代计算机中的内存空间都是按字节(byte)划分的,从理论上讲似乎任何类型的变量的访问都可以从任何地址开始,但是实际情况是在访问特定变量的时候经常需要在特定的内存地址进行访 ...