首页 > 解决方案 > 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, *args, **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...

samplePOST 到此端点的大小小于 2.5 mb 时,type(request.data)则为dict,而如果文件大小 > 2.5 mb,type(request.data)则为 django 的QueryDict.

日志:

# 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跳过这会破坏序列化。

我也在 DRF 的 github 上创建了一张票。

标签: djangodjango-rest-frameworkdjango-file-upload

解决方案


推荐阅读