八、解析器
8.1概念
解析用户请求发送过来的数据(常用的是JSON)
请求类型:
get:
方式1: http://127.0.0.1/web/?arg1=v1&arg2=v2
方式2:通过请求头发送
post:
请求头:
content-type:“urlencode…”
content-type:“application/json”
请求体:
arg1=v1&arg2=v2
{‘arg1’:'v1,‘arg2’:‘v2’}
8.2解析流程
1)读取请求头
2)根据请求头解析数据
--根据请求头获取解析器 -->如Json解析器
--request.data=解析器.parse
3)得到request.data
8.3简单应用
#视图类
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.parsers import JSONParser,FormParser
from rest_framework.negotiation import DefaultContentNegotiation
class LoginView(MyAPIView):
#用户登入,不需要认证,不需要任何权限
authentication_classes = []
permission_classes = []
#加载所有的解析器
parser_classes=[JSONParser,FormParser]
#根据请求类型,匹配对应的解析器
content_negotiation_class=DefaultContentNegotiation
def post(self,request):
# name=request.data.get('name')
# password=request.data.get('password')
print(request.data)
return Response('success')
1)使用postman以JSON形式发送请求
输出:
{'name': 'sally', 'password': '123456'}
2)使用postman以x-www-form-urlencoded形式发送请求
输出:
<QueryDict: {'name': ['sally'], 'password': ['123456']}>
8.4使用postman上传文件
#视图类
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.versioning import QueryParameterVersioning
from rest_framework.versioning import URLPathVersioning
from rest_framework.versioning import AcceptHeaderVersioning
from rest_framework.parsers import JSONParser,FormParser,FileUploadParser
from rest_framework.negotiation import DefaultContentNegotiation
class LoginView(MyAPIView):
#用户登入,不需要认证,不需要任何权限
authentication_classes = []
permission_classes = []
#加载所有的解析器(增加一个文件解析器,FileUploadParser)
parser_classes=[JSONParser,FormParser,FileUploadParser]
#根据请求类型选择对应的解析器
content_negotiation_class=DefaultContentNegotiation
def post(self,request):
# name=request.data.get('name')
# password=request.data.get('password')
print('content_type:',request.content_type)
print('request.data',request.data)
#获取request.data中的文件对象
file_obj=request.data.get('file')
print('file_name:',file_obj.name)
with open(file_obj.name,'wb') as target_file_obj:
#将用户上付的文件写入新文件
for chunk in file_obj:
target_file_obj.write(chunk)
file_obj.close()
return Response('success')
使用postman上传文件
在postman中添加一个请求头
Content-Disposition:form-data; name=“file”; filename=“django.png”
上传文件
输出:
content_type: image/png
#request.data中会有一个文件对象
request.data {'file': <InMemoryUploadedFile: django.png (image/png)>}
file_name: django.png
8.5、MultiPartParser解析器
当请求中既有普通数据又有文件时,可以使用MultiPartParser解析器
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.parsers import JSONParser,FormParser,FileUploadParser,MultiPartParser
from rest_framework.negotiation import DefaultContentNegotiation
# Create your views here.
class LoginView(MyAPIView):
#用户登入,不需要认证,不需要任何权限
authentication_classes = []
permission_classes = []
#加载所有的解析器
parser_classes=[MultiPartParser,]
#根据请求类型选择对应的解析器
content_negotiation_class=DefaultContentNegotiation
def post(self,request):
# name=request.data.get('name')
# password=request.data.get('password')
print('content_type:',request.content_type)
print('request.data',request.data)
file_obj=request.data.get('file')
print('file_name:',file_obj.name)
with open(file_obj.name,'wb') as target_file_obj:
for chunk in file_obj:
target_file_obj.write(chunk)
file_obj.close()
return Response('success')
输出:
content_type: multipart/form-data; boundary=--------------------------970019987472571630217583
#request.data中既有普通数据,又有文件
request.data <QueryDict: {'name': ['sally'], 'password': ['123456'], 'file': [<InMemoryUploadedFile: django.png (image/png)>]}>
file_name: django.png
8.6默认解析器
在视图类中默认解析器
print(self.parser_classes)
输出:
[<class 'rest_framework.parsers.JSONParser'>, <class 'rest_framework.parsers.FormParser'>, <class 'rest_framework.parsers.MultiPartParser'>]
所以drf默认的解析器就是JSONParse,FormParser和MultiPartParser
8.7解析器的全局配置
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES':['rest_framework.parsers.JSONParser','rest_framework.parsers.FormParser'],
}