Django ≥ 5.0 必须用 STORAGES 字典配置 OSS,DEFAULT_FILE_STORAGE 已废弃;END_POINT、BUCKET_NAME、BUCKET_ACL_TYPE 和 ALIYUN_OSS_CNAME 需与阿里云控制台严格一致,否则触发 403 或 bucket not found 错误。

直接用 DEFAULT_FILE_STORAGE 配置就能让 Django 文件上传走 OSS,但绝大多数人卡在 403、bucket not found、endpoint 错配这三类错误上——问题不在代码,而在配置项和阿里云控制台实际状态没对齐。
为什么上传还是走本地?检查 Django 版本和 STORAGES 配置
Django ≥ 5.0 完全废弃了 DEFAULT_FILE_STORAGE 的单值配置方式,只设它等于白设。必须改用 STORAGES 字典:
-
STORAGES会彻底覆盖DEFAULT_FILE_STORAGE和STATICFILES_STORAGE - 运行
python manage.py shell后执行from django.core.files.storage import default_storage; print(default_storage.__class__),输出里必须含AliyunMediaStorage或OssMediaStorage才算生效 - 如果你用的是
django-aliyun-oss2-storage,STORAGES["default"]["BACKEND"]应为"aliyun_oss2_storage.backends.AliyunMediaStorage" - 用
django-oss-storage则对应"django_oss_storage.backends.OssMediaStorage"
END_POINT 和 BUCKET_NAME 填错是 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-cn-shanghai.aliyuncs.com) -
BUCKET_NAME必须和阿里云 OSS 控制台「Bucket 列表」里显示的**完整名称**一模一样(区分大小写、不能带/或路径) - 如果控制台创建 Bucket 时选了「公共读」,但代码里设了
BUCKET_ACL_TYPE = "private",上传成功但 URL 返回 403 —— 因为生成的签名 URL 默认按 private 权限签,而 public-read 的 bucket 不需要签名 - 临时调试可加
ALIYUN_OSS_CNAME = ""(空字符串),避免自定义域名或 HTTPS 配置干扰
上传后 URL 是签名链接还是公开链接?由两个地方决定
不是代码“生成”的,而是 OSS 服务端策略 + 配置共同决定的。
立即学习“Python免费学习笔记(深入)”;
-
BUCKET_ACL_TYPE = "public-read"且未设ALIYUN_OSS_CNAME:URL 形如https://<bucket>.oss-<region>.aliyuncs.com/<path>,公开可访问 -
BUCKET_ACL_TYPE = "private":url()方法返回带签名的临时链接(含?Expires=...),过期即失效 - 设了
ALIYUN_OSS_CNAME(如"cdn.example.com"):所有 URL 都走这个域名,但必须确保 DNS 解析和 HTTPS 证书已就绪,否则前端加载失败
最容易被忽略的是:OSS 的 ACL 类型、ALIYUN_OSS_CNAME、END_POINT 三者必须逻辑自洽。哪怕只有一处不匹配,比如 endpoint 写成杭州却把 bucket 创建在北京,或者 cname 指向了未备案的域名,都会导致前端资源 404 或 403,且错误日志里往往不报具体原因。


















