前言

上一篇分析了请求模块的源码,如下:

def initialize_request(self, request, *args, **kwargs):
"""
Returns the initial request object.
"""
parser_context = self.get_parser_context(request) return Request(
request,
parsers=self.get_parsers(),
authenticators=self.get_authenticators(),
negotiator=self.get_content_negotiator(),
parser_context=parser_context
)

上述源码中parsers=self.get_parsers()就是解析模块源码的入口

源码分析

我们点击get_parsers进入查看该方法

def get_parsers(self):
"""
Instantiates and returns the list of parsers that this view can use.
"""
return [parser() for parser in self.parser_classes]

该方法实例化并返回此视图可以使用的解析器列表,我们点击parser_classes,查看解析器列表

api_settings = APISettings(None, DEFAULTS, IMPORT_STRINGS)

parser_classes = api_settings.DEFAULT_PARSER_CLASSES

我们会发现解析器列表,是从api_settings中的DEFAULT_PARSER_CLASSES查找的,而api_settings又等于APISettings中的DEFAULTS,我们可以从settings中的DEFAUITS列表的DEFAULT_PARSER_CLASSES,如下:

DEFAULTS = {
# Base API policies
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
],
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.FormParser',
'rest_framework.parsers.MultiPartParser'
],
}

我们可以看到,drf默认的解析器列表中有3个解析器,这3个解析器中都有media_type属性,代表支持解析的数据提交类型

  • JSONParser:media_type = 'application/json'
  • FormParser:media_type = 'application/x-www-form-urlencoded'
  • MultiPartParser: media_type = 'multipart/form-data'

如果我们想在以上3个解析器的基础上,再加上文件类型的解析器,那么需要全局配置。

全局配置

我们可以在settings.py文件中设置REST_FRAMEWORK配置,具体设置如下:

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

这样,我们以后所有继承于APIView的类视图都可以解析上面配置的4种数据类型,但是如果我们想某个视图只能解析json格式的数据,那么就需要局部配置

局部配置

默认全局配置是因为我们写的视图继承自APIViewAPIView中配置了类属性parser_classes,所以我们自己编写的视图函数中,也设置个类属性,并且导入JSONParser解析器

from rest_framework.parsers import JSONParser
class TestView(APIView):
# 局部解析类配置
parser_classes = [JSONParser] def post(self, request, *args, **kwargs):
print(request.data)
return Response("drf post ok")

接着我们使用application/x-www-form-urlencoded提交数据,会有如下报错

{
"detail": "不支持请求中的媒体类型 “application/x-www-form-urlencoded”。"
}

然后我们使用multipart/form-data提交数据,也会报错

{
"detail": "不支持请求中的媒体类型 “multipart/form-data; boundary=--------------------------022567055086460827891894”。"
}

最后我们使用application/json提交数据,响应成功

"drf post ok"

自定义解析器

如果我们想自定义一个解析器,也很简单,默认的3个解析器都继承自BaseParser,我们查看下源码

class BaseParser:
"""
All parsers should extend `BaseParser`, specifying a `media_type`
attribute, and overriding the `.parse()` method.
"""
media_type = None def parse(self, stream, media_type=None, parser_context=None):
"""
Given a stream to read from, return the parsed representation.
Should return parsed data, or a `DataAndFiles` object consisting of the
parsed data and files.
"""
raise NotImplementedError(".parse() must be overridden.")

如果我们需要自定义解析器,那么就必须继承自BaseParser,并且设置属性media_type,还要重写parse方法,有需求的小伙伴可以自行尝试,这里就不演示了

Django(49)drf解析模块源码分析的更多相关文章

  1. Django(51)drf渲染模块源码分析

    前言 渲染模块的原理和解析模块是一样,drf默认的渲染有2种方式,一种是json格式,另一种是模板方式. 渲染模块源码入口 入口:APIView类中dispatch方法中的:self.response ...

  2. Django(48)drf请求模块源码分析

    前言 APIView中的dispatch是整个请求生命过程的核心方法,包含了请求模块,权限验证,异常模块和响应模块,我们先来介绍请求模块 请求模块:request对象 源码入口 APIView类中di ...

  3. Django(50)drf异常模块源码分析

    异常模块源码入口 APIView类中dispatch方法中的:response = self.handle_exception(exc) 源码分析 我们点击handle_exception跳转,查看该 ...

  4. Django 之 restframework 解析器源码分析

    解析器分类: 1. JSONPaser ----> 解析 JSON-serialized data (解析JSON序列化的数据) 2.FormParser ---->解析form 表单中 ...

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

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

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

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

  7. nginx健康检查模块源码分析

    nginx健康检查模块 本文所说的nginx健康检查模块是指nginx_upstream_check_module模块.nginx_upstream_check_module模块是Taobao定制的用 ...

  8. Zepto事件模块源码分析

    Zepto事件模块源码分析 一.保存事件数据的handlers 我们知道js原生api中要移除事件,需要传入绑定时的回调函数.而Zepto则可以不传入回调函数,直接移除对应类型的所有事件.原因就在于Z ...

  9. Spark Scheduler模块源码分析之TaskScheduler和SchedulerBackend

    本文是Scheduler模块源码分析的第二篇,第一篇Spark Scheduler模块源码分析之DAGScheduler主要分析了DAGScheduler.本文接下来结合Spark-1.6.0的源码继 ...

随机推荐

  1. SQL优化-大数据量分页优化

    百万数据量SQL,在进行分页查询时会出现性能问题,例如我们使用PageHelper时,由于分页查询时,PageHelper会拦截查询的语句会进行两个步骤 1.添加 select count(*)fro ...

  2. 浅谈程序设计和C语言

    学前必备知识 程序:一组计算机能识别和执行的指令. 计算机语言:计算机工作基于二进制,计算机只能识别和接受由0和1组成的指令. 计算机能直接识别和接受的二进制代码称为机器指令.机器指令的集合就是该计算 ...

  3. Python 使用xlsxwriter绘制Excel表格

    最近在统计资产,正好看到了xlsxwriter这个表格生成模块,借此机会,熟悉一下,写点有趣的小案例,一开始想使用C++ QT图形化开发一套自动化运维平台,但后来发现不仅消耗时间而且需要解决QT Qs ...

  4. hdu4126(MST + 树形dp

    题意:       这个题目和hdu4756差不多,是给你一个图,然后是q次改变边的权值,权值只增不减,最后问你每次改变之后的最小树的平均值是多少. 思路:(prim+树形dp)       先跑一边 ...

  5. hdu4882 水贪心

    题意:      给你n个任务,每个任务有两个权值,t[i],b[i],前面的是完成任务所需时间,后面的那个是个参数,每个任务完成的代价是完成当前任务总时间(之前的+现在的) sumt * b[i], ...

  6. Android so注入( inject)和Hook(挂钩)的实现思路讨论

    本文博客:http://blog.csdn.net/qq1084283172/article/details/54095995 前面的博客中分析一些Android的so注入和Hook目标函数的代码,它 ...

  7. Android进程so注入Hook java方法

    本文博客链接:http://blog.csdn.net/qq1084283172/article/details/53769331 Andorid的Hook方式比较多,现在来学习下,基于Android ...

  8. hdu2492 数状数组或者线段树

    题意:      给你一些人,每个人有自己的攻击力,输入的顺序就是每个人的顺序,他们之间互相比赛,两个人比赛的条件是必须在他们两个位置之间找到一个人当裁判,这个裁判的攻击力必须在他们两个人之间,问你最 ...

  9. Java中常见的包

    目录 JDK自带的包 第三方包 JDK自带的包 JAVA提供了强大的应用程序接口,既JAVA类库.他包含大量已经设计好的工具类,帮助程序员进行字符串处理.绘图.数学计算和网络应用等方面的工作.下面简单 ...

  10. CVE-2012-1876:Internet Exporter MSHTML.DLL CaculateMinMax 堆溢出简单分析

    0x01 2012 Pwn2Own 黑客大赛 Pwn2Own 是世界上最著名的黑客大赛,意在激励白帽黑客们进行顶尖的安全研究.在 2012 年 Pwn2Own 大赛上,来自法国著名的安全团队 Vupe ...