You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django REST Framework大文件上传限制测试方案咨询

问题分析

你尝试的几种方法都存在问题:

  • 方法1:生成超大字节串直接触发内存溢出,完全不可行。
  • 方法2:InMemoryUploadedFile的size参数需要传入整数,你传了lambda函数,实际生效的是BytesIO内容的长度("large_content"共13字节),所以验证器拿到的size是13。
  • 方法3:你patch的是类的size属性,但每个InMemoryUploadedFile实例初始化时都会设置自己的size属性,类属性的patch不会覆盖实例已有的属性,因此无效。
  • 方法4:验证器直接读取file.size属性,根本没调用os.path.getsize,mock这个方法完全没用。

正确测试方案

创建一个小体积的合法UploadedFile实例,然后patch该实例的size属性为超过限制的值,既不会触发内存溢出,又能让验证器读取到预期的超大size。

测试序列化器示例

from django.test import TestCase
from django.core.files.uploadedfile import SimpleUploadedFile
from unittest.mock import patch
from your_app.serializers import YourImageSerializer  # 替换为你的序列化器类

class FileUploadValidationTest(TestCase):
    def test_large_file_rejected(self):
        # 创建小文件避免内存问题
        small_file = SimpleUploadedFile(
            name="test.jpg",
            content=b"small_test_content",
            content_type="image/jpeg"
        )
        
        # Patch实例的size为1GB(超过100MB限制)
        with patch.object(small_file, 'size', new=10**9):
            serializer = YourImageSerializer(data={"image_file": small_file})
            
            # 验证不通过
            self.assertFalse(serializer.is_valid())
            
            # 检查错误信息
            self.assertIn("image_file", serializer.errors)
            self.assertEqual(
                serializer.errors["image_file"][0],
                "Maximum file size is 100000000.0"
            )

测试API接口示例

如果你想直接测试上传接口而非序列化器:

def test_upload_large_file_api(self):
    small_file = SimpleUploadedFile("test.jpg", b"small", content_type="image/jpeg")
    
    with patch.object(small_file, 'size', new=10**9):
        client = APIClient()
        response = client.post(
            "/your/upload/endpoint/",  # 替换为你的接口路径
            {"image_file": small_file},
            format="multipart"
        )
        
        # 验证返回400错误
        self.assertEqual(response.status_code, 400)
        self.assertIn("image_file", response.data)

可选优化:友好的错误提示

你可以修改验证器,将字节数格式化为更易读的单位:

def get_file_size_validator(max_size_bytes):
    def validator_func(file):
        if file.size > max_size_bytes:
            max_size_mb = max_size_bytes / (1024 * 1024)
            raise ValidationError(f"Maximum file size is {max_size_mb:.1f}MB")
    return validator_func

内容的提问来源于stack exchange,提问作者Huzaifa Qamer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 12:07:08