解析器
# 1. 解析器介绍
对请求的数据进行分析:是针对请求体进行解析的。表示服务器可以解析的数据格式的种类
#如果是这样的格式发送的数据,在POST里面有值
Content-Type: application/url-encoding.....
request.body
request.POST
#如果是发送的json的格式,在POST里面是没有值的,在body里面有值,可通过decode,然后loads取值
Content-Type: application/json.....
request.body
request.POST
2
3
4
5
6
7
8
9
# 2. 解析器类型
我们先来看看postman 的body中,有哪些解析器:
# 2.1 form-data
就是http请求中的multipart/form-data,它会将表单的数据处理为一条消息,以标签为单元,用分隔符分开。既可以上传键值对,也可以上传文件。当上传的字段是文件时,会有Content-Type来说明文件类型;content-disposition,用来说明字段的一些信息;
由于有boundary隔离,所以multipart/form-data既可以上传文件,也可以上传键值对,它采用了键值对的方式,所以可以上传多个文件,在springmvc中可以使用MultipartHttpServletRequest接收通过api根据"name"获取不同的键值,也可以通过MulTipartFile数组接收多个文件。
**简单点说:**除了上传文本(Text)之外,还可以上传文件(File)
# 2.2 x-www-form-urlencoded
就是application/x-www-from-urlencoded,会将表单内的数据转换为键值对,&分隔。 当form的action为get时,浏览器用x-www-form-urlencoded的编码方式,将表单数据编码为 (name1=value1&name2=value2…),然后把这个字符串append到url后面,用?分隔,跳转 到这个新的url。 当form的action为post时,浏览器将form数据封装到http body中,然后发送到server。 这个格式不能提交文件。
**简单点说:**只能上传文本,不能上文件。
# 2.3 raw
可以上传任意格式的文本,可以上传text、json、xml、html等
# 2.4 binary
相当于Content-Type:application/octet-stream,从字面意思得知,只可以上传二进制数据,通常用来上传文件,由于没有键值,所以,一次只能上传一个文件。
**简单点说:**就是传二进制的数据。
# 2.5 multipart/form-data与x-www-form-urlencoded区别?
multipart/form-data:既可以上传文件等二进制数据,也可以上传表单键值对,只是最后会转化为一条信息;
x-www-form-urlencoded:只能上传键值对,并且键值对都是间隔分开的。
# 3. 解析器使用
# 3.1 视图
说明:parser_classes = [],可配置多个解释器,但是只针对当前视图。
from rest_framework.parsers import FormParser, JSONParser, FileUploadParser, MultiPartParser
from rest_framework.views import APIView
from django.http import HttpResponse
class ParserView(APIView):
parser_classes = [JSONParser] #只支持JSON解释器,局部,只针对这个视图
def post(self, request, *args, **kwargs):
# print("body:", request.body.decode())
print("content_type:", request.content_type)
# 获取请求的值,并使用对应的JSONParser进行处理
print("data:", request.data)
# application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值
print("POST:", request.POST)
print("FILES:", request.FILES)
return HttpResponse('响应')
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
接下来,我们看下FormParser解析器和JSONParser解析器的源码:Ctrl+FormParser 和 Ctrl+JSONParser:
class FormParser(BaseParser): #FormParser解析器
"""
Parser for form data.
"""
media_type = 'application/x-www-form-urlencoded'
.....
class JSONParser(BaseParser): #JSONParser解析器
"""
Parses JSON-serialized data.
"""
media_type = 'application/json'
renderer_class = renderers.JSONRenderer
strict = api_settings.STRICT_JSON
2
3
4
5
6
7
8
9
10
11
12
13
14
15
由此得出:
- 请求头为application/x-www-form-urlencoded 需要解析器 FormParser
- 请求头为application/json 需要解析器 JSONParser
- MultiPartParser 用来解析 form_data
# 3.2 路由
说明:需要在子路由下配置
from django.urls import path
from app06 import views
urlpatterns = [
path('parse/', views.ParserView.as_view(), name='parser')
]
2
3
4
5
6
# 3.3、postman测试
1、json格式传字符串(符合条件)
输出结果:application/json的数据都是在 request.data中。
content_type: application/json
[07/May/2020 17:26:58] "POST /api/parse/ HTTP/1.1" 200 6
data: {'name': '寻仙二', 'status': 0}
POST: <QueryDict: {}>
FILES: <MultiValueDict: {}>
2
3
4
5
2、form-data格式传字符串(不符合条件)
输出结果:
Unsupported Media Type: /api/parse/
content_type: multipart/form-data; boundary=--------------------------165365745998366525194613
[07/May/2020 17:28:22] "POST /api/parse/ HTTP/1.1" 415 132
2
3
总结:
- application/x-www-form-urlencoded 或 multipart/form-data时,request.POST才有值
- application/json 的 request.POST中没有值,值在 request.data中。
# 4. 默认解析器
现在我们使用的解析器,都是我们自己配置的,那我们看看,django restframe work给我们的默认解析器是啥呐。让我们一起来看看吧!
因为我们 的视图类继承的是 APIView 先来走一波:Ctrl + APIView
class APIView(View):
...
parser_classes = api_settings.DEFAULT_PARSER_CLASSES #默认解析器
...
2
3
4
5
来继续: Ctrl + api_settings:
api_settings = APISettings(None, DEFAULTS, IMPORT_STRINGS)
go on,我们来看看 DEFAULTS 定义的是啥:Ctrl + DEFAULTS:
DEFAULTS = {
...,
'DEFAULT_PARSER_CLASSES': (
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.FormParser',
'rest_framework.parsers.MultiPartParser'
),
....
}
2
3
4
5
6
7
8
9
哈哈,找到了:默认是 JSONParser、FormParser、MultiPartParser。那既然这样的话,其实解析器不需要我们自己去配置,除非你需要特定只需要某一两种解析器。