rest framework 之解析器
一、示例
1、api/urls.py
from django.urls import path, re_path
from api.views import UserView, ParserView
urlpatterns = [
# path('users/', UserView.as_view()),
re_path('(?P<version>[v1|v2]+)/users/', UserView.as_view(), name='api_user'),
path('parser/', ParserView.as_view(), name='api_parer'), # 添加这句
]
2、api/views.py
JSONParser:只能解析content-type:application/json的头FormParser:只能解析content-type:application/x-www-form-urlencoded的头
from rest_framework.parsers import JSONParser, FormParser
class ParserView(APIView):
parser_classes = [JSONParser, FormParser]
def post(self, request, *args, **kwargs):
print(request.data)
return HttpResponse('解析')
3、使用 postman 发送 json 数据测试后台是否能解析:
(1)、设置为 post 方式,headers 中添加数据类型为 json

(2)、body 中选择 raw,然后选择 json 类型,最后就是在空白处构建要发送的 json 数据(记得是双引号):

后台结果:

如果是 content-type:application/x-www-form-urlencoded 类型数据,不需要设置请求头,默认就是。但是 body 中需要设置为 x-www-form-urlencoded 。
二、源码分析
1、dispatch()
def dispatch(self, request, *args, **kwargs):
"""
`.dispatch()` is pretty much the same as Django's regular dispatch,
but with extra hooks for startup, finalize, and exception handling.
"""
self.args = args
self.kwargs = kwargs
# 对原生的 request 对象进行加工,丰富了
# request= Request(request,parsers=self.get_parsers(),authenticators=self.get_authenticators(),negotiator=self.get_content_negotiator(),parser_context=parser_context)
# 第一个参数为原生的 request 对象,封装原生 request
request = self.initialize_request(request, *args, **kwargs)
self.request = request
self.headers = self.default_response_headers # deprecate?
try:
self.initial(request, *args, **kwargs)
# Get the appropriate handler method
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(),
self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
response = handler(request, *args, **kwargs)
except Exception as exc:
response = self.handle_exception(exc)
self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response
2、initialize_request()
def initialize_request(self, request, *args, **kwargs):
"""
Returns the initial request object. 封装原生 request 对象
"""
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
)
3、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]
4、parser_classes
class APIView(View):
# The following policies may be set at either globally, or per-view.
renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES
# 从 settings 中获取解析器
parser_classes = api_settings.DEFAULT_PARSER_CLASSES
# Allow dependency injection of other settings to make testing easier.
settings = api_settings
5、全局配置解析器 settings:
REST_FRAMEWORK = {
# 解析器
"DEFAULT_PARSER_CLASSES":["rest_framework.parsers.JSONParser","rest_framework.parsers.FormParser"]
}
源码流程图

根据请求头 content-type 选择对应的解析器就请求体内容进行处理。
三、仅处理请求头 content-type 为 application/json 的请求体
1、urls.py
from django.urls import path, re_path, include
from api.views import TestView2
urlpatterns = [
re_path(r'(?P<version>[v1|v2]+)/test2', TestView2.as_view()),
]
2、views.py
rom rest_framework.views import APIView
from rest_framework.parsers import JSONParser, FormParser
from rest_framework.response import Response
class TestView2(APIView):
parser_classes = [JSONParser]
def post(self, request, *args, **kwargs):
print(request.content_type) # application/json
# 获取请求值,并发 JSONParser 处理
print(request.data) # {'name': 'rose', 'age': 18}
# application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值
print(request.POST) # <QueryDict: {}>
print(request.FILES) # <MultiValueDict: {}>
return Response('响应内容')

四、仅处理请求头 content-type 为 application/x-www-form-urlencoded 的请求体
1、urls.py
from django.urls import path, re_path, include
from api.views import TestView2
urlpatterns = [
re_path(r'(?P<version>[v1|v2]+)/test2', TestView2.as_view()),
]
2、views.py
rom rest_framework.views import APIView
from rest_framework.parsers import JSONParser, FormParser
from rest_framework.response import Response
class TestView2(APIView):
parser_classes = [FormParser]
def post(self, request, *args, **kwargs):
print(request.content_type) # application/x-www-form-urlencoded
# 获取请求值,并发 JSONParser 处理
print(request.data) # <QueryDict: {'123': ['']}>
# application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值
print(request.POST) # <QueryDict: {'123': ['']}>
print(request.FILES) # <MultiValueDict: {}>
return Response('响应内容')
五、仅处理请求头content-type为multipart/form-data的请求体
1、urls.py
from django.urls import path, re_path, include
from api.views import TestView2
urlpatterns = [
re_path(r'(?P<version>[v1|v2]+)/test2', TestView2.as_view()),
]
2、views.py
rom rest_framework.views import APIView
from rest_framework.parsers import JSONParser, FormParser, MultiPartParser
from rest_framework.response import Response
class TestView2(APIView):
parser_classes = [MultiPartParser]
def post(self, request, *args, **kwargs):
print(request.content_type) # multipart/form-data
# 获取请求值,并发 JSONParser 处理
print(request.data)
# application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值
print(request.POST)
print(request.FILES)
return Response('响应内容')
3、upload.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="http://127.0.0.1:8000/test/" method="post" enctype="multipart/form-data">
<input type="text" name="user" />
<input type="file" name="img">
<input type="submit" value="提交">
</form>
</body>
</html>
六、仅上传文件
1、urls.py
from django.urls import path, re_path, include
from api.views import TestView2
urlpatterns = [
re_path(r'(?P<version>[v1|v2]+)/test2', TestView2.as_view()),
]
2、views.py
rom rest_framework.views import APIView
from rest_framework.parsers import JSONParser, FormParser, MultiPartParser, FileUploadParser
from rest_framework.response import Response
class TestView2(APIView):
parser_classes = [FileUploadParser]
def post(self, request, *args, **kwargs):
print(request.content_type)
# 获取请求值,并发 JSONParser 处理
print(request.data)
# application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值
print(request.POST)
print(request.FILES)
return Response('响应内容')
3、upload.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="http://127.0.0.1:8000/test/" method="post" enctype="multipart/form-data">
<input type="text" name="user" />
<input type="file" name="img">
<input type="submit" value="提交">
</form>
</body>
</html>
七、其他
多个 parser
当同时使用多个 parser 时,rest framework 会根据请求头 content-type 自动进行比对,并使用对应 parser
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request
from rest_framework.parsers import JSONParser, FormParser, MultiPartParser
class TestView(APIView):
parser_classes = [JSONParser, FormParser, MultiPartParser, ]
def post(self, request, *args, **kwargs):
print(request.content_type)
# 获取请求的值,并使用对应的JSONParser进行处理
print(request.data)
# application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值
print(request.POST)
print(request.FILES)
return Response('POST请求,响应内容')
全局使用
settings.py
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES':[
'rest_framework.parsers.JSONParser'
'rest_framework.parsers.FormParser'
'rest_framework.parsers.MultiPartParser'
]
}
Tips: 个别特殊的值可以通过Django的request对象 request._request 来进行获取
总结
JSONParser,解析数据类型:content-type:application/jsonFormParser,解析数据类型:content-type:application/x-www-form-urlencoded- 支持全局配置解析器类型
rest framework 之解析器的更多相关文章
- Django Rest framework 之 解析器
RESTful 规范 django rest framework 之 认证(一) django rest framework 之 权限(二) django rest framework 之 节流(三) ...
- DRF Django REST framework 之 解析器(二)
引入 Django Rest framework帮助我们实现了处理application/json协议请求的数据,如果不使用DRF,直接从 request.body 里面拿到原始的客户端请求的字节数据 ...
- Django Rest Framework之解析器
基本代码结构 urls.py: from django.conf.urls import url, include from web.views.s5_parser import TestView u ...
- Django REST framework的解析器与渲染器
解析器 解析器的作用 解析器的作用就是服务端接收客户端传过来的数据,把数据解析成自己可以处理的数据.本质就是对请求体中的数据进行解析. 在了解解析器之前,我们要先知道Accept以及ContentTy ...
- django的rest framework框架——版本、解析器、序列化
一.rest framework的版本使用 1.版本可以写在URL中,通过GET传参,如 http://127.0.0.1:8082/api/users/?version=v1 (1)自定义类获取版本 ...
- Django高级篇三。restful的解析器,认证组件,权限组件
一.rest=framework之解析器 1)解析器作用. 根据提交的数据.只解析某些特定的数据.非法数据不接收,为了系统安全问题 比如解析的数据格式有 有application/json,x-www ...
- Django rest framework(5)----解析器
目录 Django rest framework(1)----认证 Django rest framework(2)----权限 Django rest framework(3)----节流 Djan ...
- Restful framework【第五篇】解析器
基本使用 -解析器 -源码从request.data -全局配置 -'DEFAULT_PARSER_CLASSES':['rest_framework.parsers.JSONParser'], -局 ...
- python-django rest framework框架之解析器
1.解析器 : 对请求的数据进行解析 - 请求体进行解析. 解析器在你不拿请求体数据时 不会调用. class UsersView(APIView): def get(self,request,*ar ...
随机推荐
- ZROI 暑期高端峰会 A班 Day5 计算几何
内积(点积) 很普及组,不讲了. \[(a,b)^2\le(a,a)(b,b)\] 外积(叉积) 也很普及组,不讲了. 旋转 对于矩阵 \(\begin{bmatrix}\cos\theta\\\si ...
- 软件工程卷1 抽象与建模 (Dines Bjorner 著)
I 开篇 1. 绪论 II 离散数学 2. 数 (已看) 3. 集合 4. 笛卡尔 5. 类型 6. 函数 7. λ演算 8. 代数 9. 数理逻辑 III 简单RSL 10. RSL中的原子类型和值 ...
- JS- 数组去重方法整理
[indexOf] 简单而且可以加中文,但是兼容性不好,indexOF兼容到ie9 function uniq(arr) { var temp = []; for (let i = 0; i < ...
- wkhtmltopdf cpdf HTML转pdf 及pdf合并
将 html 转为 pdf :wkhtmltopdf wkhtmltopdf 是一个使用 webkit 网页渲染引擎开发的用来将 html 转成 pdf 的工具,可以跟多种脚本语言进行集成来转换文档. ...
- 关于qt creator各种假死的问题
来自CSDN网友( qq191329827)内容,亲自尝试,且经历一致: 我有两个笔记本,1个台式机,都装了qt, 然后,我的thinkpad x1c,装上之后creator各种假死,网上看了好多解决 ...
- Java集合详解4:一文读懂HashMap和HashTable的区别以及常见面试题
<Java集合详解系列>是我在完成夯实Java基础篇的系列博客后准备开始写的新系列. 这些文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查 ...
- ReentrantReadWriteLock源码分析
代码在后面 读锁 = 共享锁 读锁写锁,公用一个Sync AQS state. 写锁是排他的,看到有人获取锁,他不会去获取,他获取了锁,别人也不会进来获取锁. 写锁的获取跟ReentarntLock一 ...
- javascript 函数的暂停和恢复
javascript 异步编程从来都是一个难题,最开始我们用 callback,但随之触发了回调地狱,于是"发明" Promise 解决 callback 嵌套过深的问题.然而由于 ...
- FRP represents an intersection of two programming paradigms.
FRP represents an intersection of two programming paradigms. Functional programming Functional progr ...
- .net core将URL请求格式化为XML或JSON(网站动态生成sitemap.xml)
.net core将URL请求格式化为XML或JSON(网站动态生成sitemap.xml) 首先设置 Startup.cs 文件 配置 ConfigureServices services .Add ...