django ≥ 5.0 必须用 storages 字典配置替代 default_file_storage,否则该设置被完全忽略;验证需在 shell 中检查 default_storage.__class__ 是否含 aliyunmediastorage 等目标类名。

为什么 DEFAULT_FILE_STORAGE 配置后上传仍走本地?
不是代码写错,而是 Django 版本升级后配置方式变了。Django ≥ 5.0 完全弃用 DEFAULT_FILE_STORAGE,改用 STORAGES 字典配置——只设 DEFAULT_FILE_STORAGE 会被忽略。
验证是否生效:进 python manage.py shell,执行 from django.core.files.storage import default_storage; print(default_storage.__class__),输出类名必须含 AliyunMediaStorage 或 S3Boto3Storage 才算成功。
- Django 4.x 及以下:设
DEFAULT_FILE_STORAGE = 'aliyun_oss2_storage.backends.AliyunMediaStorage' - Django 5.0+:必须用
STORAGES,且"default"键对应 media,"staticfiles"对应 static - 别漏掉
INSTALLED_APPS加上对应 app(如'aliyun_oss2_storage'或'storages')
OSS / S3 的 endpoint、bucket、ACL 怎么填才不报 403 或 bucket not found?
错误信息里其实已经告诉你答案了。比如日志里出现 HostId: xxx.oss-cn-hangzhou.aliyuncs.com,说明你该用 oss-cn-hangzhou.aliyuncs.com,而不是抄文档里的示例值。
-
END_POINT必须和 Bucket 所在区域严格一致,格式为oss-<region>.aliyuncs.com</region>(OSS)或s3.<region>.amazonaws.com</region>(S3) -
BUCKET_NAME必须和控制台「Bucket 列表」里显示的**完整名称**一模一样(区分大小写、不含路径) -
BUCKET_ACL_TYPE(OSS)或AWS_S3_OBJECT_PARAMETERS(S3)要和 Bucket 实际权限匹配:设成"public-read"却在 private bucket 上用,URL 返回 403;反之,private bucket 却生成公开 URL,会 403 - 临时调试建议设
ALIYUN_OSS_CNAME = ""或清空AWS_S3_CUSTOM_DOMAIN,避免自定义域名干扰
大文件上传卡住或 OOM,根本原因是什么?
不是网络慢,是 Django 默认把整个文件读进内存再处理。100MB 文件触发 MemoryError,或被 Gunicorn/Nginx 杀掉进程,本质是没绕过 request.FILES 这条链路。
- 绝对不要在视图里调用
request.FILES['file'].read()—— 这是最常踩的 OOM 坑 - 禁用内存缓冲:
FILE_UPLOAD_MAX_MEMORY_SIZE = 0(强制走磁盘临时文件) - 但更彻底的解法是前端直传:用 STS 临时凭证 + POST Policy,让浏览器直接 PUT 到 OSS/S3 endpoint,Django 只签发凭证、接收回调、落库元数据
- 若必须走 Django 中转,得用流式上传:
boto3.client.upload_fileobj(request.body, ...),并校验Content-Length头
Django Admin 里 ImageField 显示异常或验证失败怎么办?
不是图片坏了,是默认的 PIL 校验逻辑依赖本地文件系统,而 OSS/S3 路径无法被 Image.open() 直接打开。
- 禁用
ImageField自带校验:重写模型字段,加validators=[],或在 form 中覆盖clean_*方法 - 替换成 HTTP HEAD 校验 MIME:用
requests.head(url, timeout=3)检查Content-Type是否为image/* - Admin 上传 UI 会尝试调用
save_form_data写本地,需重写formfield()并绑定自定义 widget,否则上传按钮点完没反应 - 字段存
CharField而非ImageField更可控:存oss_key,读取时拼 URL,避免底层 storage 抽象层干扰
真正难的不是配通,而是搞清“谁在读文件”——是浏览器直传,还是 Django 在内存里 load,还是 Admin 表单偷偷调了本地 write。每种路径对应的陷阱完全不同,混在一起就永远在修同一个报错。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











