SuperAPI AI 工具集

django-storages-s3

部署与运维

查看项目

更新于 10-15 12:57

技能介绍

Django Storages S3 是一项面向资深 Django 开发者的技能,用于通过 django-storages 和 boto3 在 AWS S3 上实现生产级文件存储,涵盖公开与私有媒体文件、静态文件、预签名 URL 以及 CloudFront。

适用场景

  • 从 AWS S3 而非本地文件系统提供静态文件和/或媒体文件
  • 配置 Django 4.2+ 的 STORAGES 字典或旧版 DEFAULT_FILE_STORAGE
  • 分离公开(CDN 提供)与私有(预签名)文件后端
  • 生成预签名下载 URL 或浏览器直传 S3 的 URL
  • 为 S3 前置 CloudFront 并编写最小权限 IAM 策略
  • 在不修改代码的情况下将本地 FileField/ImageField 存储迁移到 S3
  • 在不实际访问 S3 的情况下测试存储代码

核心工作流

  1. 安装与注册 —— 执行 pip install django-storages[s3] boto3;将 "storages" 加入 INSTALLED_APPS
  2. 配置凭证 —— 从环境变量加载或依赖附加的 IAM 角色;切勿硬编码
  3. 连接 STORAGES 字典 —— 为默认(媒体)与 staticfiles 后端设置各自的 location 前缀
  4. 添加命名后端 —— 需要时在 STORAGES 中额外配置公开与私有桶/ACL 条目
  5. 验证与测试 —— 运行 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 策略、常见陷阱)

最小可用示例

以下片段展示了核心的必须遵守约束:从环境变量加载凭证、STORAGES 字典、媒体与静态分离的 location,以及媒体后端上的 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,而非虚构名称。
  • Locations —— 确认默认(媒体)与 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 字典(相同配置适用于 5.2 LTS 与 6.0);DEFAULT_FILE_STORAGE/STATICFILES_STORAGE 在 5.1 中已移除,仅保留给 < 4.2
  • 在任何签发预签名 URL 的后端上设置 custom_domain=None
  • 在测试中模拟 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 dict、预签名 URL、generate_presigned_post、CloudFront、IAM 策略、InMemoryStorage、moto

相关技能

  • django-expert —— 核心 Django 模型、DRF 与 ORM,产生本技能持久化到 S3 的文件
  • fullstack-guardian —— 围绕已存储文件的安全端到端上传流程与访问控制
  • devops-engineer —— 为本技能目标配置 S3 桶、IAM 角色与 CloudFront 分发