一、示例

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/json
  • FormParser,解析数据类型:content-type:application/x-www-form-urlencoded
  • 支持全局配置解析器类型

rest framework 之解析器的更多相关文章

  1. Django Rest framework 之 解析器

    RESTful 规范 django rest framework 之 认证(一) django rest framework 之 权限(二) django rest framework 之 节流(三) ...

  2. DRF Django REST framework 之 解析器(二)

    引入 Django Rest framework帮助我们实现了处理application/json协议请求的数据,如果不使用DRF,直接从 request.body 里面拿到原始的客户端请求的字节数据 ...

  3. Django Rest Framework之解析器

    基本代码结构 urls.py: from django.conf.urls import url, include from web.views.s5_parser import TestView u ...

  4. Django REST framework的解析器与渲染器

    解析器 解析器的作用 解析器的作用就是服务端接收客户端传过来的数据,把数据解析成自己可以处理的数据.本质就是对请求体中的数据进行解析. 在了解解析器之前,我们要先知道Accept以及ContentTy ...

  5. django的rest framework框架——版本、解析器、序列化

    一.rest framework的版本使用 1.版本可以写在URL中,通过GET传参,如 http://127.0.0.1:8082/api/users/?version=v1 (1)自定义类获取版本 ...

  6. Django高级篇三。restful的解析器,认证组件,权限组件

    一.rest=framework之解析器 1)解析器作用. 根据提交的数据.只解析某些特定的数据.非法数据不接收,为了系统安全问题 比如解析的数据格式有 有application/json,x-www ...

  7. Django rest framework(5)----解析器

    目录 Django rest framework(1)----认证 Django rest framework(2)----权限 Django rest framework(3)----节流 Djan ...

  8. Restful framework【第五篇】解析器

    基本使用 -解析器 -源码从request.data -全局配置 -'DEFAULT_PARSER_CLASSES':['rest_framework.parsers.JSONParser'], -局 ...

  9. python-django rest framework框架之解析器

    1.解析器 : 对请求的数据进行解析 - 请求体进行解析. 解析器在你不拿请求体数据时 不会调用. class UsersView(APIView): def get(self,request,*ar ...

随机推荐

  1. django -- 实现ORM登录

    前戏 上篇文章写了一个简单的登录页面,那我们可不可以实现一个简单的登录功能呢?如果登录成功,给返回一个页面,失败给出错误的提示呢? 在之前学HTML的时候,我们知道,网页在往服务器提交数据的时候,都是 ...

  2. iptables 数据走向流程

    链的规则存放于哪些表中(从链到表的对应关系): PREROUTING 的规则可以存在于:raw表,mangle表,nat表. INPUT 的规则可以存在于:mangle表,filter表,(cento ...

  3. Python 3.X 练习集100题 05

    用 *号输出字母 C的图案 方法1: print(" ***** ") print(" ** * ") print(" ** ") prin ...

  4. linux lnmp环境下 安装apache教程

    linux lnmp环境下 安装apache教程 源码安装 apr ,apr-util 安装apache要用<pre>wget http://mirrors.cnnic.cn/apache ...

  5. Rancher 构建 CI/CD 自动化流程 - 动态配置 Jenkins-slave(二)

    一.说明 1.1 说明 前面介绍采用 Jenkinsfile + KubernetesPod.yaml 方式进行部署项目(Rancher 构建 CI/CD 自动化流程 - 动态配置 Jenkins-s ...

  6. | C语言I作业02

    C语言I博客作业02 标签: 18软件2班 李煦亮 问题 答案 这个作业属于那个课程 C语言程序设计I 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/C ...

  7. idea 2019.2 版本把菜单栏隐藏了恢复办法

    一不小心把idea的菜单栏给隐藏了(如图) ,搞了半天也恢复不了,网上也没有找到什么办法,可是搞得我焦头烂额呀,怎么找也找不到,也不见大神有过提示,最后没办法,想着去看看它的配置文件吧,于是便找到了默 ...

  8. 词向量实践(gensim)

    词向量训练步骤: 分词并去停用词 词频过滤 训练 项目完整地址:https://github.com/cyandn/practice/tree/master/Word2Vec gensim中Word2 ...

  9. [转帖]Linux crontab 查看所有用户的crontab任务

    Linux crontab 查看所有用户的crontab任务 https://www.cnblogs.com/xzlive/p/11542176.html 查看所有用户的crontab任务 - mlz ...

  10. 第四节:配置的读取、StartUp类、内置依赖注入和扩展改造

    一. 配置的读取 在Asp.Net Core中,有一个 appsettings.json 文件,用于存储相应的配置信息,读取的时,要通过构造函数注入:IConfiguration Configurat ...