如何解决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 举报,一经查实,本站将立刻删除。