我尝试将ImageField
添加到名为LucyGuide
的模型中,该模型会使用django-storages
将用户上传的图像保存到S3。这是(简化)模型:
class LucyGuide(TimeStampedModel):
headshot = models.ImageField(upload_to='uploads/', null=True)
bio = models.TextField(blank=True)
我已将以下内容添加到settings.py
:
# Use Boto3 backend to interact with Amazon's S3
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
# Amazon S3 credentials (for django-storages)
AWS_ACCESS_KEY_ID = os.getenv('AWS_ACCESS_KEY_ID', default='')
AWS_SECRET_ACCESS_KEY = os.getenv('AWS_SECRET_ACCESS_KEY', default='')
AWS_STORAGE_BUCKET_NAME = os.getenv('AWS_STORAGE_BUCKET_NAME', default='')
AWS_S3_REGION_NAME = os.getenv('AWS_S3_REGION_NAME')
AWS_S3_OBJECT_PARAMETERS = {
'CacheControl': 'max-age=86400',
}
# Use v4 of the signing protocol (recommended for all new projects)
AWS_S3_SIGNATURE_VERSION = 's3v4'
从.env
文件中读取实际密钥(使用类似于django-decouple
的机制)。
为了试试这个,我在Django的管理界面中为LucyGuide
上传了一张随机图片:
在shell中,我可以访问指南url
字段的headshot
属性,该字段确实是AWS存储桶的链接:
In [6]: guide = LucyGuide.objects.filter(bio__startswith="Kristen").first()
In [7]: guide
Out[7]: <LucyGuide: Kristen Hoover>
In [8]: guide.headshot
Out[8]: <ImageFieldFile: uploads/320px-Waaah.jpg>
In [9]: guide.headshot.url
Out[9]: 'https://lucy-prod.s3.amazonaws.com/uploads/320px-Waaah.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIMC2A%2F20180327%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20180327T200248Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=ae75dbdd75d13020113c12ef2d655e3'
(我删除了部分网址)。问题是,当我尝试在浏览器中访问此URL时,我得到一个&#34;这个XML文件似乎没有任何与之关联的样式信息&#34;错误:
<Error>
<Code>AuthorizationQueryParametersError</Code>
<Message>
Error parsing the X-Amz-Credential parameter; the region 'us-east-1' is wrong; expecting 'us-west-1'
</Message>
<Region>us-west-1</Region>
<RequestId>1E053D94011E400F</RequestId>
<HostId>
jbkRHVj2y6ygppTsAo2+uOXgby0ok0mbsFsRogKqbu9jPMb+9eGe24nJv441vip3WpmwpFqlsYg=
</HostId>
</Error>
我已经尝试通过添加AWS_S3_REGION_NAME
设置来解决此问题(参见http://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html)。由错误消息指示的区域us-west-1
似乎是正确的,因为存储桶设置在&#34;美国西部(加利福尼亚州北部)&#34;:
总而言之,尽管设置了正确的AWS_S3_REGION_NAME
,我仍然不明白为什么会出现此错误。我该如何解决这个错误?
更新
如果我检查桶中的物体,我发现它有一个&#34; Link&#34;这比url
字段的headshot
属性生成的简单得多:
我正在考虑对基本网址进行硬编码&#39;此处显示的是API端点我试图构建检索图像URL,但这似乎不是一个优雅的解决方案。有更好的想法吗?
答案 0 :(得分:1)
通过阅读(并设置断点)django-storages
源代码,我能够通过添加设置来解决问题
AWS_QUERYSTRING_AUTH = False
将其从默认值True
更改。现在url
属性生成一个没有身份验证查询字符串的URL:
In [2]: guide = LucyGuide.objects.filter(bio__startswith='Darrell').first()
In [3]: guide.headshot
Out[3]: <ImageFieldFile: uploads/Waaah.jpg>
In [4]: guide.headshot.url
Out[4]: 'https://lucy-prod.s3.amazonaws.com/uploads/Waaah.jpg'
答案 1 :(得分:0)
您可以简单地使用AWS_S3_REGION_NAME =''us-east-2''#将us-east-2替换为您的区域,而不是关闭查询字符串。更安全。