You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Debug=False时Django后台无法上传图片至AWS S3求助

Django生产环境(DEBUG=False)下S3媒体文件上传/显示问题排查与解决

1. 修复S3权限配置(核心问题)

当前配置仅开放了读取权限,完全未允许上传操作,这是图片无法上传的直接原因:

调整桶策略,添加上传权限

给对应IAM用户(而非所有匿名用户)添加上传相关权限,修改后的桶策略示例(替换为你的IAM用户ARN):

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::djangoecomproject/*"
        },
        {
            "Sid": "AllowIAMUserUpload",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::你的AWS账号ID:user/你的IAM用户名"
            },
            "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": "arn:aws:s3:::djangoecomproject/*"
        }
    ]
}

更新CORS规则,允许上传方法

当前CORS仅支持GET/HEAD,需添加PUT方法以支持上传请求:

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "GET",
            "HEAD",
            "PUT"
        ],
        "AllowedOrigins": [
            "https://django-ecom-candles-production.up.railway.app"
        ],
        "ExposeHeaders": []
    }
]

2. 验证Django生产环境媒体文件配置

确保settings.py中以下配置正确:

# 存储后端配置
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
AWS_STORAGE_BUCKET_NAME = 'djangoecomproject'
AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID')  # 用环境变量,禁止硬编码密钥
AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY')
AWS_S3_REGION_NAME = '你的桶所在区域'  # 例如us-east-1
AWS_S3_URL_PROTOCOL = 'https'  # 强制HTTPS访问

# 媒体文件URL配置
MEDIA_URL = f'https://{AWS_STORAGE_BUCKET_NAME}.s3.{AWS_S3_REGION_NAME}.amazonaws.com/'
  • 生产环境必须用Railway的环境变量管理功能注入密钥,绝对不能硬编码
  • 确认已安装依赖:pip install django-storages[boto3]

3. 排查boto3测试异常

你的测试代码仅做了桶内容查询,缺少上传测试且未指定区域,修改测试代码:

import boto3
import os

AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY')
BUCKET_NAME = 'djangoecomproject'
REGION_NAME = '你的桶所在区域'

try:
    s3 = boto3.client(
        's3',
        aws_access_key_id=AWS_ACCESS_KEY_ID,
        aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
        region_name=REGION_NAME  # 必须指定桶所在区域
    )

    # 测试上传文件
    s3.put_object(Bucket=BUCKET_NAME, Key='test_upload.txt', Body='测试内容')
    print("上传测试完成,前往S3桶查看文件")

    # 测试列出桶内容
    response = s3.list_objects_v2(Bucket=BUCKET_NAME)
    if 'Contents' in response:
        for obj in response['Contents']:
            print(f"文件: {obj['Key']}")
    else:
        print("桶内无文件")

except Exception as e:
    print(f"错误: {e}")
  • 若仍看不到文件,检查IAM用户是否拥有s3:PutObject和s3:ListBucket权限
  • 确认桶的实际区域与代码中REGION_NAME一致

4. 修复后台图片显示问题

  • 确保上传文件的权限为公开可读:可在Django配置中添加AWS_DEFAULT_ACL = 'public-read'(注意:公开桶需评估安全风险)
  • 清除浏览器缓存,或给媒体URL添加版本参数避免缓存干扰
  • 检查后台管理页面的图片URL是否正确指向S3域名,而非本地路径

内容的提问来源于stack exchange,提问作者kitty333

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 17:04:54