一般来说,现在传输的数据形式主要是json,但是也包括form,file形式,那么我们看看在drf框架中如何接受这些数据。
from django.shortcuts import render
from rest_framework.utils.urls import replace_query_param
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.versioning import QueryParameterVersioning, BaseVersioning,URLPathVersioning,AcceptHeaderVersioning
from rest_framework import exceptions
from rest_framework.parsers import JSONParser,FormParser,FileUploadParser,MultiPartParser
from rest_framework.negotiation import DefaultContentNegotiation
# Create your views here.
class HomeView(APIView):
parser_classes =[MultiPartParser]
content_negotiation_class =DefaultContentNegotiation
def post(self,request,*args,**kwargs):
# self.dispatch
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('请求成功')
我们来看看这个解析器,JSONParser,FormParser,FileUploadParser,MultiPartParser,这四个解析器,分别处理json,form,文件,文件加数据这四种类型,大概得原理是找到这个content-type是什么类型,然后根据DefaultContentNegotiation,来获得处理后的数据
大概的原理:
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 = 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
进入dispatch函数,第8行,我们进去
def initialize_request(self, request, *args, **kwargs):
"""
Returns the initial request object.
"""
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
)
这里面封装了parsers,content_negotiator,这里的parser_context获得的是调用这个函数的对象,以及传入的数据,这也为后面解析数据埋下伏笔,这个时候,他并没有进行任何的数据处理,当我们调用request.data的时候,才会进行数据的处理,我们进入封装的request的data方法看看
@property
def data(self):
if not _hasattr(self, '_full_data'):
self._load_data_and_files()
return self._full_data
从里面的大概意思上来看,就是如果这里面有数据了,那么就直接返回,如果还没有数据,那么就自行加载数据,感兴趣的可以细看这里面的流程,这里就不细说了。
我们可以依次来接受想要的数据,根据自己选择数据类型,他默认的parsers也可以根据self.parsers来查看,当然也可以在全局中进行配置,这些和前面的认证组件的原理都类似,这里就不再赘述。