28.解析器Parser
- 因为前后端分离,可能有json、xml、html等各种不同格式的内容
- 后端也必须要有一个解析器来解析前端发送过来的数据
- 不然后端无法处理前端数据
- 后端有一个渲染器Render,和解析器是相反方向,将后端数据翻译成前端能明白的数据格式
- Django原生的解析器对于post的数据,如果要从request.body中解析出来放到request.POST中
- 必须满足两个条件

- REST框架提供了很多内置的Parser类,用来处理各种媒体类型的请求,比如json、xml,还支持自定义解析器
- BaseParser:解析器基类,以下四个类都直接继承他
- JSONParser
- FormParser
- MultiPartParser
- FileUploadParser
"""
BaseParser解析器基类源码
相当于是留了一个坑,被继承后重写
定义了空的 midia_type 媒体类型
定义了parse方法以及对应参数
"""
class BaseParser:
media_type = None
def parse(self, stream, media_type=None, parser_context=None):
# 没有实现实现这个方法的异常,没有写任何代码
raise NotImplementedError(".parse() must be overridden.")
'''
JSONParser解析器源码
继承BaseParser
'''
class JSONParser(BaseParser):
media_type = 'application/json' # 定义媒体类型
renderer_class = renderers.JSONRenderer #渲染器,解析是解析json那么返回也应该渲染json返回
strict = api_settings.STRICT_JSON # 限制设置
def parse(self, stream, media_type=None, parser_context=None):
# 如果有解析上下文,将parser_context赋值parser_context,否则赋值一个空字典
parser_context = parser_context or {}
# 上下文如果有编码方式,赋值给encoding,否则使用默认的编码格式
encoding = parser_context.get('encoding', settings.DEFAULT_CHARSET)
try:
#对数据流进行读取和编码的处理
decoded_stream = codecs.getreader(encoding)(stream)
#验证是否符合约束
parse_constant = json.strict_constant if self.strict else None
# 返回解码之后的数据流
return json.load(decoded_stream, parse_constant=parse_constant)
except ValueError as exc:
raise ParseError('JSON parse error - %s' % str(exc))
'''
其他解析器大同小异
'''
- DRF将有效的解析器集定义为类的列表。当 request.data 被访问时,REST框架将检查请求头的 Content-Type 属性
- 以此来确定要使用哪个解析器来解析数据。
- 解析器只有在请求request.data的时候才会被调用!如果不需要data数据,那么就不用解析
- 在Django项目的settings.py文件中 DEFAULT_PARSER_CLASSES 进行全局的解析器设置
# 默认的解析器配置
# 几种解析器的写法没有先后顺序的要求,不像中间件那样的配置有顺序关系
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES':(
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.FormParser',
'rest_framework.parsers.MultiPartParser',
)
}
'''
如果我们配置第三方解析器 ,例如yml等
解析器和渲染器都需要配置,一般是配对使用的
配置格式:app.file.calss
'''
# 类属性指定
class TestApi(APIView):
# 通过parser_classes指定该视图的解析器,值是一个元组or list
parser_classes = (JSONParser,)
def post(self, request):
return Response('xxx')
#函数装饰器指定
from rest_framework.decorators import parser_classes
@api_view(['POST'])
@parser_classes((JSONParser,))
def testApi(request):
...
要自定义解析器,必须继承 BaseParser 类
设置 .media_type 属性
实现parse(self, stream, media_type, parser_context) 方法
该方法应返回将用于填充 request.data 属性的数据
#示例-文本解析器
class TextParser(BaseParser):
media_type = 'text/plain' #媒体类型
def parse(self, stream, media_type=None, parser_context=None):
return stream.read() #返回读取的内容
解析器区别
解析 JSON 格式的请求内容
其.media_type属性值为 application/json
解析HTML表单内容,使用QueryDict的数据填充request.data
这也是Django原生支持的解析方式。
通常同时支持FormParser和MultiPartParser两种解析器,以便完全支持HTML表单数据。
.media_type: application/x-www-form-urlencoded
解析多部分的HTML表单内容,支持文件上传
.media_type: multipart/form-data
HTML的form表单的enctype属性规定了form表单在发送数据到服务器时的编码方式
有
三种方式:
application/x-www-form-urlencoded
默认的编码方式,常用于键值对数据
但是在用文本的传输和MP3等大型文件的时候,使用这种编码效率低下
multipart/form-data
指定传输数据为二进制类型,比如图片、mp3、文件
text/plain
纯文体的传输。空格转换为 “+” 加号,但不对特殊字符编码。使用较少
解析原始文件上传内容。此时, request.data 属性将是一个字典,并且只包含一个键'file' ,对应的值包含上传的文件内容。
如果使用FileUploadParser解析器的视图,在被调用的时候URL中携带一个 filename 关键字参数
则该参数将被用作文件名。如果在没有这个关键字参数的情况下调用它,则客户端必须在
HTTP头部的 Content-Disposition 中设置文件名。例如 Content-Disposition:attachment; filename=upload.jpg
.media_type: */*
FileUploadParser 用于原生的文件上传请求。对于在浏览器中上传或者使用带有分段上传功能的客户端使用MultiPartParser 解析器
由于 FileUploadParser 的 media_type 属性值是 */* ,表示可以接受所有内容类型,所以无需指定别的解析器,指定 FileUploadParser 就足够了。
28.解析器Parser的更多相关文章
- Django-rest-framework 接口实现 分页:(Pagination) 解析器(Parser) 渲染器(renderer)
分页:(Pagination) rest_framework 中已经定义好了 3 种 分页模式 from rest_framework.pagination import PageNumberPagi ...
- easyui的解析器Parser
平时使用easyui做框架开发时,都知道easyui的模块组件能通过属性方法或js方法来渲染,本质上是通过parser解析器来处理实现的,因为多数情况下都是自动触发完成整个页面的解析,所以没有感觉到它 ...
- 通过pull解析器操作安卓的xml
通过pull解析器操作安卓的xml 例子定义了一个javabean用于存放上面解析出来的xml内容, 这个javabean为Person,代码请见本页下面备注: =================== ...
- rest framework的框架实现之 (版本,解析器,序列化,分页)
一版本 版本实现根据访问的的方式有以下几种 a : https://127.0.0.1:8000/users?version=v1 ---->基于url的get方式 #settings.pyR ...
- 黎活明8天快速掌握android视频教程--15_采用Pull解析器解析和生成XML内容
1.该项目主要有下面的两个作用 (1)将xml文件解析成对象的List对象,xml文件可以来自手机本地,也可以来自服务器返回的xml数据 (2)强list对象保存成xml文件,xml保存到手机的内存卡 ...
- 【P4语言学习】Parser解析器
参考文章:王垠:谈谈Parser 簡單介紹 P4 語言(一)- Parser 什么是Parser 传统的parser,一般出现在编译器和编译原理课程中,援引<谈谈Parser>的定义: 首 ...
- [LeetCode] Mini Parser 迷你解析器
Given a nested list of integers represented as a string, implement a parser to deserialize it. Each ...
- EasyUI基础入门之Parser(解析器)
前言 JQuery EasyUI提供的组件包含功能强大的DataGrid,TreeGrid.面板.下拉组合等.用户能够组合使用这些组件,也能够单独使用当中一个.(使用的形式是以插件的方式提供的) Ea ...
- FFmpeg的HEVC解码器源码简单分析:解析器(Parser)部分
===================================================== HEVC源码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpeg ...
随机推荐
- 多线程与高并发(五)—— 源码解析 ReentrantLock
一.前言 ReentrantLock 是基于 AQS 实现的同步框架,关于 AQS 的源码在 这篇文章 已经讲解过,ReentrantLock 的主要实现都依赖AQS,因此在阅读本文前应该先了解 AQ ...
- 【安全通报】DolphinScheduler 漏洞情况说明
Apache DolphinScheduler 社区邮件列表最近通告了 2 个漏洞,考虑到有很多用户并未订阅此邮件列表,我们特地在此进行情况说明: CVE-2020-11974[1] 漏洞 (CVE- ...
- 如果让我设计一套,TPS百万级API网关!
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 是滴,小傅哥又要准备搞事情了!这次准备下手API网关项目,因为这是所有互联网大厂都有的一个核心 ...
- C++ UAC 提权 以一个管理员身份运行程序
这里是我编译的和一个测试Demo:http://pan.baidu.com/s/1qWNgC6C 大家如果看我下边的不是很清楚,可以下载这个具体工程: 群:103197177 C++进阶讨论:欢迎喜欢 ...
- linux 旁路掉协议栈的处理点
对于协议栈的发展,目前有三种处理趋势,一种是类似于使用dpdk的方式,然后将协议栈放到用户态来做,做得比较好的一般都是以bsd的协议栈为底子,可以参考的是腾讯开源的的方案,另外一种是,继续放在内核,但 ...
- Filter(过滤器)、ThreadLocal(本地线程)、Listener(监听器)
Filter(过滤器) Filter过滤器它的作用是:拦截请求,过滤响应. 过滤器链 1)执行的顺序依次是: A B C Demo03 C2 B2 A2 2)如果采取的是注解的方式进行配置,那么过滤器 ...
- 在Laravel框架blog中,终端的一些命令
创建控制器php artisan make:controller TestController数据库迁移php artisan make:migration create_goods_table实行迁 ...
- Android平台摄像头/屏幕/外部数据采集及RTMP推送接口设计描述
好多开发者提到,为什么大牛直播SDK的Android平台RTMP推送接口怎么这么多?不像一些开源或者商业RTMP推送一样,就几个接口,简单明了. 不解释,以Android平台RTMP推送模块常用接口, ...
- centos7部署Prometheus+Grafana
一.安装Prometheus Server 请从 Prometheus 官方下载 linux 版的二进制压缩包.注意在下载前要选择操作系统为 linux. 执行下面的命令把 prometheus se ...
- Java---Stream进阶
由于本文需要有一定的Stream基础,所以如果不懂什么是Stream的同学请移步:Java---Stream入门 操作分类 graph LR 操作分类 --- 中间操作 终端操作 --- 操作分类 中 ...