drf解析器
解析器
解析器:解析请求者发送过来的数据(JSON)。针对POST请求体中数据进行解析。根据传入的数据格式和请求头来匹配解析器,解析完毕后将结果赋值给request.data。
常用数据格式:
username="赛兔子"&age=25 # form-data格式
{"user":"赛兔子","age":25} # json格式
解析器流程概述:
1、读取请求头
2、根据请求头匹配对应解析器:
先读取的content-type值,然后分别与每个解析器类中的media_type属性进行匹配,匹配成功后执行解析器类中parse()方法解析数据,解析完成后赋值到request.data;
class JSONParser(BaseParser): #Form解析器 """ Parses JSON-serialized data. """ media_type = 'application/json' def parse(self, stream, media_type=None, parser_context=None): ... class FormParser(BaseParser): #JSON解析器 """ Parser for form data. """ media_type = 'application/x-www-form-urlencoded' def parse(self, stream, media_type=None, parser_context=None): ...
3、request.data读取解析后的数据
JSONParser
urls.py
from django.urls import path from .views import UserView urlpatterns = [ path("user/",UserView.as_view()) ]
views.py
from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.parsers import JSONParser from rest_framework.negotiation import DefaultContentNegotiation # 解析器 class UserView(APIView): # 定义JSONParser解析器 parser_classes = [JSONParser, ] # 根据请求content-type值,匹配解析器 content_negotiation_class = DefaultContentNegotiation def post(self, request): print(request.content_type) # 数据类型 print(request.data) # 当调用request.data时就会触发解析动作,返回数据; return Response("...")
访问:
程序执行输出:
application/json {'age': 28}
FormParser
views.py
from rest_framework.parsers import FormParser # 解析器 class UserView(APIView): parser_classes = [FormParser, ] # 根据请求content-type值,匹配解析器 content_negotiation_class = DefaultContentNegotiation def post(self, request): print(request.content_type) print(request.data) return Response("...")
访问:
程序执行结果:
application/x-www-form-urlencoded;charset=UTF-8 <QueryDict: {'name': ['"admin"'], 'age': ['28']}>
MultiPartParser
views.py
from rest_framework.parsers import MultiPartParser # 解析器 class UserView(APIView): parser_classes = [MultiPartParser, ] # 根据请求content-type值,匹配解析器 content_negotiation_class = DefaultContentNegotiation def post(self, request): print(request.content_type) print(request.data) file_object = request.data.get("img") with open(file_object.name, mode="wb") as target_file_object: for chunk in file_object: target_file_object.write(chunk) file_object.close() return Response("...")
访问:
程序执行结果:
multipart/form-data; boundary=--------------------------260397190921806174757399 <QueryDict: {'name': ['admin'], 'img': [<InMemoryUploadedFile: 3.jpeg (image/jpeg)>]}>
FileUploadParser
views.py
from rest_framework.parsers import FileUploadParser # 解析器 class UserView(APIView): parser_classes = [FileUploadParser, ] # 根据请求content-type值,匹配解析器 content_negotiation_class = DefaultContentNegotiation def post(self, request): print(request.content_type) print(request.data) file_object = request.data.get("file") with open(file_object.name, mode="wb") as target_file_object: for chunk in file_object: target_file_object.write(chunk) file_object.close() return Response("...")
访问:
上传文件:
程序执行结果:
text/plain {'file': <InMemoryUploadedFile: upload.jpg (text/plain)>}
多个解析器
views.py
from rest_framework.parsers import FileUploadParser,JSONParser,FormParser from rest_framework.negotiation import DefaultContentNegotiation # 解析器 class UserView(APIView): #所有的解析器 parser_classes = [FileUploadParser, JSONParser,FileUploadParser] # 两个功能:1、根据请求,匹配对应的解析器;2、寻找渲染器 content_negotiation_class = DefaultContentNegotiation def post(self, request): pass
默认解析器
视图中不用定义任意解析器,drf已经为我们提供了默认解释器,drf会自动去调用执行解析动作;
api_settings.py
REST_FRAMEWORK = { 'DEFAULT_PARSER_CLASSES': [ 'rest_framework.parsers.JSONParser', 'rest_framework.parsers.FormParser', 'rest_framework.parsers.MultiPartParser', ], }