微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Django:当上传的文件大小 > DATA_UPLOAD_MAX_MEMORY_SIZE 时跳过 MultiPartParser

如何解决Django:当上传的文件大小 > DATA_UPLOAD_MAX_MEMORY_SIZE 时跳过 MultiPartParser

我的 DRF 应用程序中有一个视图接受 Content-type: multipart/form-data,我用它来将多个文件一起发布,

代码

from rest_framework.parsers import MultiPartParser
from rest_framework.decorators import api_view,parser_classes
from rest_framework import serializers as rfs

class CustomMultiPartParser(MultiPartParser):
    def parse(self,stream,*args,**kwargs):
        print("----- inside MultiPartJSONParser ------") ## for debug
        req = super().parse(stream,**kwargs)
        data_str = req.data.get("data",None)
        if data_str:
            parsed = json.loads(data_str)
            mutable_data = {"data": parsed}
            mutable_files = {}
            for key,value in req.files.items():
                if key != "data":
                    mutable_files[key] = value
            return parsers.DataAndFiles(mutable_data,mutable_files)

        return req

class CustomFileSerializer(rfs.Serializer):
    data = datafieldSerializer()
    sample = rfs.FileField()

@api_view(["POST"])
@parser_classes((CustomMultiPartParser,))
def my_view(request):
   print(type(request.data)) ## for debug
   serializer = CustomFileSerializer(data=request.data)
   serializer.is_valid(raise_exception=True)
    # ...snip...

当发布到此端点的 sample 的大小小于 2.5 mb 时,type(request.data)dict 而如果文件大小 > 2.5 mb,则 type(request.data) 是 django 的 { {1}}。

日志:

QueryDict

在调试更多时,我发现:

  • 2.5mb 的阈值是 django 的 DATA_UPLOAD_MAX_MEMORY_SIZE。当我将此变量设置为更高的值时,阈值就变成了那个。

  • 在第二种情况下,# file size < 2.5mb ----- inside MultiPartJSONParser ------ {'data': {'private': False},'sample': <InMemoryUploadedFile: pafish.exe (application/x-ms-dos-executable)>} # file size > 2.5mb <QueryDict: {'data': '[{"private": false}]','sample': [<TemporaryUploadedFile: wannacry.bin (application/octet-stream)>]}>> 一起被跳过。由于跳过了解析,CustomMultiPartParser 仍然是一个字符串(如日志中所示),它破坏了序列化,响应为:

    request.data["data"]
  • 我认为问题可能出在 {"errors":{"data":["This field is required."]}} 上,所以在我的 TemporaryUploadedFile 中,我强制它只将 settings.py 用于:

    TemporaryUploadFile

    但我也遇到了同样的问题,当文件大小 > 2.5mb (FILE_UPLOAD_HANDLERS = ["django.core.files.uploadhandler.TemporaryFileUploadHandler"] ) 时,CustomMultiPartParser 会被一起跳过。

我无法理解为什么跳过了破坏序列化的 DATA_UPLOAD_MAX_MEMORY_SIZE

我也在 DRF 的 github 上创建了一个 ticket

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。