drf框架的解析器和内容协商

一般来说,现在传输的数据形式主要是json,但是也包括form,file形式,那么我们看看在drf框架中如何接受这些数据。

python 复制代码
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,来获得处理后的数据 大概的原理:

python 复制代码
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行,我们进去

python 复制代码
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方法看看

python 复制代码
@property
def data(self):
    if not _hasattr(self, '_full_data'):
        self._load_data_and_files()
    return self._full_data

从里面的大概意思上来看,就是如果这里面有数据了,那么就直接返回,如果还没有数据,那么就自行加载数据,感兴趣的可以细看这里面的流程,这里就不细说了。 我们可以依次来接受想要的数据,根据自己选择数据类型,他默认的parsers也可以根据self.parsers来查看,当然也可以在全局中进行配置,这些和前面的认证组件的原理都类似,这里就不再赘述。

相关推荐
jessecyj26 分钟前
SpringBoot详解
java·spring boot·后端
爱吃的小肥羊33 分钟前
刚刚!Claude最强大模型泄露,Anthropic紧急封锁
后端
qqty121734 分钟前
Spring Boot管理用户数据
java·spring boot·后端
bearpping1 小时前
SpringBoot最佳实践之 - 使用AOP记录操作日志
java·spring boot·后端
一叶飘零_sweeeet1 小时前
线上故障零扩散:全链路监控、智能告警与应急响应 SOP 完整落地指南
java·后端·spring
开心就好20253 小时前
不同阶段的 iOS 应用混淆工具怎么组合使用,源码混淆、IPA混淆
后端·ios
架构师沉默3 小时前
程序员如何避免猝死?
java·后端·架构
椰奶燕麦3 小时前
Windows PackageManager (winget) 核心故障排错与通用修复指南
后端
zjjsctcdl3 小时前
springBoot发布https服务及调用
spring boot·后端·https
zdl6864 小时前
Spring Boot文件上传
java·spring boot·后端