Django配置S3Boto3Storage后出现NoneType相关报错如何解决
问题根因排查
你遇到的报错核心是S3配置参数不合法,具体有几个明显错误:
- 密钥参数拼写错误:配置中写的
AWS_SECRET_ACESSS_KEY是错误命名,正确参数为AWS_SECRET_ACCESS_KEY,多输入了一个S导致密钥永远读取为None,是触发所有NoneType相关报错的核心原因 - 布尔参数取值错误:
AWS_QUERYSTRING_AUTH、AWS_S3_FILE_OVERWRITE要求传入布尔值,直接用os.environ.get读取要么返回字符串要么返回None,没有做类型转换也没有默认值,参数不符合boto3的要求 - DEBUG判断逻辑错误:
if os.getcwd == '/app'中os.getcwd是方法没有加调用括号,永远返回方法对象不可能等于字符串,导致DEBUG状态异常,无法拿到完整报错信息 - 模板对ImageField的调用不兼容S3:
'ImageFieldFile' object is not subscriptable报错是因为模板中大概率对ImageField对象做了下标取值操作,S3存储返回的ImageFieldFile结构和本地存储不同,原有写法不兼容
修复步骤
- 修正拼写错误的密钥参数
# 把原来错误的AWS_SECRET_ACESSS_KEY替换成正确写法 AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY')
注意同步修正对应环境变量的命名,不要保留拼写错误。
- 修正布尔参数的取值逻辑,增加默认值
# 自动把环境变量的字符串转成布尔值,缺失时默认设为False AWS_QUERYSTRING_AUTH = os.environ.get('AWS_QUERYSTRING_AUTH', 'False').lower() == 'true' AWS_S3_FILE_OVERWRITE = os.environ.get('AWS_S3_FILE_OVERWRITE', 'False').lower() == 'true'
- 修正DEBUG判断逻辑,增加方法调用括号
if os.getcwd() == '/app': DEBUG = False # 可以把S3存储配置移到生产环境判断内,本地开发默认用本地存储避免配置S3参数 DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage' else: DEBUG = True
- 增加配置校验逻辑,启动前提前检查参数完整性
可以在settings.py末尾增加校验代码,避免运行时才触发报错:
# 校验S3必填参数是否完整 REQUIRED_S3_PARAMS = [AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_STORAGE_BUCKET_NAME] if DEFAULT_FILE_STORAGE == 'storages.backends.s3boto3.S3Boto3Storage' and not all(REQUIRED_S3_PARAMS): raise ValueError("S3存储配置缺失,请检查AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY、AWS_STORAGE_BUCKET_NAME环境变量是否正确配置")
- 修正模板中ImageField的调用逻辑
不要对ImageField对象直接取下标,先判断文件存在再取URL:
{% if 实例对象.图片字段 %} <img src="{{ 实例对象.图片字段.url }}" alt="图片"> {% else %} <img src="/static/默认图片路径.png" alt="默认图片"> {% endif %}
内容的提问来源于stack exchange,提问作者Angel Hernandez
相关产品推荐
相关产品推荐

