关于 django-storages-s3
面向 Django 项目的技能,介绍如何使用 django-storages 和 boto3 配置、审查生产环境的 AWS S3 文件存储。涵盖静态与媒体文件、公有与私有后端、预签名 URL,以及无需访问真实 S3 的测试。
主要功能
- 01配置 Django STORAGES 使用 S3
- 02分离静态文件与媒体文件
- 03设置公有和私有后端
- 04生成预签名 URL
- 05在测试中模拟 S3
- 06审查 IAM 与存储设置
适用场景
- 01将 Django 上传文件从本地迁至 S3
- 02通过 CloudFront 提供静态文件
- 03提供私有下载或上传链接
- 04不连接 S3 测试存储行为
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ jeffallan/ claude-skills --skill django-storages-s3安装后在 Claude Code 中输入/django-storages-s3确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/configuration.mdcustom-backends.mdpresigned-urls.mdtesting-storages.md详细介绍
Django Storages S3
专注于 Django 的高级工程师,擅长通过 django-storages 和 boto3 在 AWS S3 上构建生产级文件存储——包括公开和私有媒体文件、静态文件、预签名 URL 以及 CloudFront。
何时使用此技能
- 从 AWS S3 而非本地文件系统提供静态文件和/或媒体文件
- 配置 Django 4.2+ 的
STORAGES字典或旧版DEFAULT_FILE_STORAGE - 分离公开(由 CDN 提供服务)和私有(使用预签名 URL)文件后端
- 生成预签名下载 URL,或生成供浏览器直接上传到 S3 的 URL
- 在 S3 前置 CloudFront,并编写遵循最小权限原则的 IAM 策略
- 将本地
FileField/ImageField存储迁移到 S3,无需更改代码 - 在不访问 S3 的情况下测试存储代码
核心工作流
- 安装并注册 —
pip install django-storages[s3] boto3;将"storages"添加到INSTALLED_APPS - 配置凭据 — 从环境变量加载凭据,或使用已附加的 IAM 角色;切勿硬编码
- 配置
STORAGES字典 — 为default(媒体文件)和staticfiles后端设置不同的location前缀 - 添加命名后端 — 有需要时,将公开与私有存储桶/ACL 拆分为额外的
STORAGES条目 - 验证并测试 — 运行
collectstatic,确认上传的文件进入 S3,并在测试中使用InMemoryStorage或moto模拟 S3
参考指南
根据上下文加载详细指南:
| 主题 | 参考文档 | 适用场景 |
|---|---|---|
| 设置与 STORAGES | references/configuration.md | 核心设置、4.2+ 与旧版对比、CloudFront |
| 自定义后端 | references/custom-backends.md | 公开与私有存储桶、按字段配置存储 |
| 预签名 URL | references/presigned-urls.md | 下载链接、浏览器直接上传 |
| 测试与 IAM | references/testing-storages.md | 模拟 S3、IAM 策略、常见问题 |
最小可用示例
以下代码片段展示了核心 MUST DO 约束:从环境变量加载凭据、使用 STORAGES 字典、分开配置媒体/静态文件位置,以及在媒体后端设置 default_acl=None。
# settings.py
import os
AWS_STORAGE_BUCKET_NAME = os.environ["AWS_STORAGE_BUCKET_NAME"]
AWS_S3_REGION_NAME = os.environ.get("AWS_S3_REGION_NAME", "us-east-1")
AWS_S3_CUSTOM_DOMAIN = f"{AWS_STORAGE_BUCKET_NAME}.s3.{AWS_S3_REGION_NAME}.amazonaws.com"
# On EC2/ECS/Lambda, omit keys entirely — boto3 uses the attached IAM role.
STORAGES = {
"default": { # media uploads
"BACKEND": "storages.backends.s3boto3.S3Boto3Storage",
"OPTIONS": {
"bucket_name": AWS_STORAGE_BUCKET_NAME,
"location": "media",
"default_acl": None, # rely on bucket policy, not per-object ACLs
"file_overwrite": False,
"querystring_auth": False, # public objects → clean URLs
},
},
"staticfiles": {
"BACKEND": "storages.backends.s3boto3.S3StaticStorage",
"OPTIONS": {
"bucket_name": AWS_STORAGE_BUCKET_NAME,
"location": "static",
},
},
}
MEDIA_URL = f"https://{AWS_S3_CUSTOM_DOMAIN}/media/"
STATIC_URL = f"https://{AWS_S3_CUSTOM_DOMAIN}/static/"
# models.py — uploads go straight to S3 on save()
from django.db import models
class Document(models.Model):
file = models.FileField(upload_to="docs/") # uses STORAGES["default"]
审查现有配置
审查已在使用 S3 的项目时(而非从头搭建),请按此清单逐项检查——每一项都是将下方某个约束改写为“查找 X,确认 Y”:
- 凭据 —
grep -rn "AWS_SECRET_ACCESS_KEY\|aws_secret" settings/→ 确认值来自os.environ/django-environ或 IAM 角色,而不是提交到代码仓库中的字面值。 - ACL —
grep -rn "default_acl\|AWS_DEFAULT_ACL" .→ 对于 2023 年 4 月之后创建的存储桶,所有值都必须为None。任何"public-read"/"private"都会引发AccessControlListNotSupported;公开访问应通过存储桶策略配置。 - 存储后端 — 确认 Django 4.2+ 使用
STORAGES字典,而不是DEFAULT_FILE_STORAGE/STATICFILES_STORAGE(这些设置已在 Django 5.1 中移除,因此在 5.1/5.2/6.0 中会被静默忽略);确认静态文件类是S3StaticStorage,而不是凭空编造的名称。 - 位置 — 确认
default(媒体文件)和staticfiles使用不同的location前缀或存储桶,避免collectstatic与上传文件发生冲突。 - 区域 — 确认
region_name(或全局设置AWS_S3_REGION_NAME)与存储桶的实际区域一致,并确认对于非us-east-1存储桶,AWS_S3_CUSTOM_DOMAIN包含区域段。 - 预签名 — 对于私有后端,确认
querystring_auth=True且custom_domain=None;确认预签名.url()的结果不会在AWS_QUERYSTRING_EXPIRE之后继续缓存。 - 覆盖清理 — 若设置了
file_overwrite=False,确认替换文件时会显式删除旧文件(否则被取代的对象会一直残留)。 - IAM — 确认策略仅对存储桶 ARN 授予
Get/Put/Delete/ListBucket权限,而非授予更广泛的 S3 访问权限。
约束
必须做到
- 从环境变量或绑定的 IAM 角色加载 AWS 凭证
- 设置
default_acl=None,让存储桶策略(而非对象 ACL)控制访问权限 - 为静态文件和媒体文件设置不同的
location前缀,或使用不同的存储桶 - 在 Django 4.2+ 中使用
STORAGES字典(Django 5.2 LTS 和 6.0 的配置方式相同);DEFAULT_FILE_STORAGE/STATICFILES_STORAGE已在 5.1 中移除,仅在低于 4.2 的版本中使用 - 对任何会生成预签名 URL 的后端设置
custom_domain=None - 在测试中使用 Mock S3(
InMemoryStorage或moto),而非访问真实存储桶
绝不能做
- 不要在
settings.py中硬编码AWS_SECRET_ACCESS_KEY,也不要提交该密钥 - 不要将
querystring_auth=True与custom_domain混用(预签名会失效) - 不要在同一前缀下混放静态文件和媒体文件
- 授予 IAM 用户的权限不要超出存储桶 ARN 上的
Get/Put/Delete/ListBucket权限 - 不要依赖 2023 年 4 月之后创建的存储桶中的对象 ACL(默认已禁用 ACL)
知识参考
django-storages、S3Boto3Storage、S3StaticStorage、boto3、STORAGES 字典、预签名 URL、generate_presigned_post、CloudFront、IAM 策略、InMemoryStorage、moto
相关技能
django-expert— 核心 Django 模型、DRF 和 ORM 会生成此技能持久化到 S3 的文件fullstack-guardian— 安全的端到端上传流程,以及对存储文件的访问控制devops-engineer— 配置此技能所使用的 S3 存储桶、IAM 角色和 CloudFront 分发
评论
支持 Markdown