mcpField
D
django-storages-s3

django-storages-s3

github.com/jeffallan云与 DevOps12.1k953 次安装今天更新
代码仓库

关于 django-storages-s3

面向 Django 项目的技能,介绍如何使用 django-storages 和 boto3 配置、审查生产环境的 AWS S3 文件存储。涵盖静态与媒体文件、公有与私有后端、预签名 URL,以及无需访问真实 S3 的测试。

主要功能

  1. 01配置 Django STORAGES 使用 S3
  2. 02分离静态文件与媒体文件
  3. 03设置公有和私有后端
  4. 04生成预签名 URL
  5. 05在测试中模拟 S3
  6. 06审查 IAM 与存储设置

适用场景

  1. 01将 Django 上传文件从本地迁至 S3
  2. 02通过 CloudFront 提供静态文件
  3. 03提供私有下载或上传链接
  4. 04不连接 S3 测试存储行为

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/jeffallan/claude-skills --skill django-storages-s3

安装后在 Claude Code 中输入/django-storages-s3确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
configuration.md
custom-backends.md
presigned-urls.md
testing-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 的情况下测试存储代码

核心工作流

  1. 安装并注册 — pip install django-storages[s3] boto3;将 "storages" 添加到 INSTALLED_APPS
  2. 配置凭据 — 从环境变量加载凭据,或使用已附加的 IAM 角色;切勿硬编码
  3. 配置 STORAGES 字典 — 为 default(媒体文件)和 staticfiles 后端设置不同的 location 前缀
  4. 添加命名后端 — 有需要时,将公开与私有存储桶/ACL 拆分为额外的 STORAGES 条目
  5. 验证并测试 — 运行 collectstatic,确认上传的文件进入 S3,并在测试中使用 InMemoryStorage 或 moto 模拟 S3

参考指南

根据上下文加载详细指南:

主题参考文档适用场景
设置与 STORAGESreferences/configuration.md核心设置、4.2+ 与旧版对比、CloudFront
自定义后端references/custom-backends.md公开与私有存储桶、按字段配置存储
预签名 URLreferences/presigned-urls.md下载链接、浏览器直接上传
测试与 IAMreferences/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”:

  1. 凭据 — grep -rn "AWS_SECRET_ACCESS_KEY\|aws_secret" settings/ → 确认值来自 os.environ/django-environ 或 IAM 角色,而不是提交到代码仓库中的字面值。
  2. ACL — grep -rn "default_acl\|AWS_DEFAULT_ACL" . → 对于 2023 年 4 月之后创建的存储桶,所有值都必须为 None。任何 "public-read"/"private" 都会引发 AccessControlListNotSupported;公开访问应通过存储桶策略配置。
  3. 存储后端 — 确认 Django 4.2+ 使用 STORAGES 字典,而不是 DEFAULT_FILE_STORAGE/STATICFILES_STORAGE(这些设置已在 Django 5.1 中移除,因此在 5.1/5.2/6.0 中会被静默忽略);确认静态文件类是 S3StaticStorage,而不是凭空编造的名称。
  4. 位置 — 确认 default(媒体文件)和 staticfiles 使用不同的 location 前缀或存储桶,避免 collectstatic 与上传文件发生冲突。
  5. 区域 — 确认 region_name(或全局设置 AWS_S3_REGION_NAME)与存储桶的实际区域一致,并确认对于非 us-east-1 存储桶,AWS_S3_CUSTOM_DOMAIN 包含区域段。
  6. 预签名 — 对于私有后端,确认 querystring_auth=True 且 custom_domain=None;确认预签名 .url() 的结果不会在 AWS_QUERYSTRING_EXPIRE 之后继续缓存。
  7. 覆盖清理 — 若设置了 file_overwrite=False,确认替换文件时会显式删除旧文件(否则被取代的对象会一直残留)。
  8. 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