django - Django:上传文件大小> DATA_UPLOAD_MAX_MEMORY_SIZE 时跳过 MultiPartParser
问题描述
我在我的 DRF 应用程序中有一个视图,它接受Content-type: multipart/form-data
我用来将多个文件一起发布的视图,
sample
表示一个二进制文件data
是一个字符串化的 JSON。
代码:
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...
当sample
POST 到此端点的大小小于 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)>]}>>
在调试更多时,我发现:
2.5mb 阈值是 django 的DATA_UPLOAD_MAX_MEMORY_SIZE。当我将此变量设置为更高的值时,阈值就变成了这个值。
在
CustomMultiPartParser
第二种情况下一起跳过。由于跳过了解析,request.data["data"]
因此仍然是一个字符串(如日志中所示),它破坏了序列化,响应为:{"errors":{"data":["This field is required."]}}
我认为问题可能出在 上
TemporaryUploadedFile
,所以在我的 中settings.py
,我强迫它只用于TemporaryUploadFile
:FILE_UPLOAD_HANDLERS = ["django.core.files.uploadhandler.TemporaryFileUploadHandler"]
但是我也遇到了同样的问题,
CustomMultiPartParser
当文件大小 > 2.5mb ( ) 时一起跳过DATA_UPLOAD_MAX_MEMORY_SIZE
。
我无法理解为什么CustomMultiPartParser
跳过这会破坏序列化。
我也在 DRF 的 github 上创建了一张票。
解决方案
推荐阅读
- python - 如何使用 Python 从变量中保存新结果?
- android - 前台服务在 Android 10 中被杀死
- c++ - 无符号字符范围是 0 到 255
- quarkus - 请求已被读取 - 使用 graphql
- amazon-web-services - 通过 cloudformation 使用 aws `cdk synth` 输出
- javascript - 反转 L:CRS 的 Y 轴。Vue2-Leaflet 上的简单地图
- django - Ngnix Django 502 错误网关
- authentication - 来自非浏览器客户端的 SAML(或其他)身份验证流程
- linear-programming - 如何用语言编写以下目标函数的语法
- c++ - 霍夫圆检测确定性