Django和S3直接上传

2024-04-27 00:17:23 发布

您现在位置:Python中文网/ 问答频道 /正文

在我的项目中,我已经配置好了S3storages。现在我尝试使用s3 direct配置直接上传到s3。它工作得很好。用户可以上传图像并将其存储在S3中。当我在数据库中保存对图像的引用时,问题就来了。在

模型.py

class FullResPicture(Audit):
    docfile = models.ImageField()
    picture = models.OneToOneField(Picture, primary_key=True)

设置.py

^{pr2}$

视图.py

#Doc file is the url to the image that the user uploaded directly to S3
#https://s3-eu-west-1.amazonaws.com/bucket/uploads/imgs/picture.jpeg
fullRes = FullResPicture(docfile = form_list[1].cleaned_data['docfile'])

因此,如果我查看我的数据库,我得到了一些工作正常的图像(我只使用django存储上传的图像),docfile值如下:

images/2015/08/11/image.jpg

当应用程序尝试访问这些图像时,s3boto能够正确地获取图像。在

但是我有直接从用户浏览器上传的图片。对于这些,我存储了完整的url,因此它们在数据库中如下所示:

https://s3-eu-west-1.amazonaws.com/bucket/uploads/imgs/Most-Famous-Felines-034.jpg

当应用程序试图访问它们时,我遇到了一个异常:

File "/Users/mariopersonal/Documents/dev/venv/pictures/lib/python2.7/site-packages/django/db/models/fields/files.py", line 49, in _get_file
    self._file = self.storage.open(self.name, 'rb')
  File "/Users/mariopersonal/Documents/dev/venv/pictures/lib/python2.7/site-packages/django/core/files/storage.py", line 35, in open
    return self._open(name, mode)
  File "/Users/mariopersonal/Documents/dev/venv/pictures/lib/python2.7/site-packages/storages/backends/s3boto.py", line 363, in _open
    name = self._normalize_name(self._clean_name(name))
  File "/Users/mariopersonal/Documents/dev/venv/pictures/lib/python2.7/site-packages/storages/backends/s3boto.py", line 341, in _normalize_name
    name)
SuspiciousOperation: Attempted access to 'https:/s3-eu-west-1.amazonaws.com/bucket/uploads/imgs/Most-Famous-Felines-034.jpg' denied.

所以很明显,s3boto不喜欢将文件引用作为完整的url。在

为了排除故障,我尝试硬编码保存的值,因此它只保存最后一部分,而不是完整的url,但是当它试图访问图像时,我遇到了另一个异常:

IOError: File does not exist: uploads/imgs/Most-Famous-Felines-034.jpg

有人知道这里出了什么问题吗?有没有人有直接上传到s3的实例,它在模型中存储对上传文件的引用?在

谢谢。在


Tags: namepy图像selfurls3usersdocuments
1条回答
网友
1楼 · 发布于 2024-04-27 00:17:23

这是我修正的方法,以防对别人有帮助。如果您已经让django-storages正常工作django-s3direct从客户端上载图像,但无法使它们协同工作,则此解决方案适用于。在

用同一个桶

我做的第一件事是确保django存储和django-s3direct都配置为使用同一个bucket。由于django存储和django-s3direct已经分别工作,只需检查它们是否使用相同的bucket。对于大多数用户,只需执行以下操作:

设置.py

^{1}$

注意,我们使用的是AWS_STORAGE_BUCKET_NAME,它应该为django存储配置定义。在

在我的情况下,有点复杂,因为我使用不同的桶为不同的模型。在

只储存钥匙

当使用s3direct时,一旦用户上传了图片并提交了表单,我们的视图将收到s3放置图片的url。如果我们存储这个url,当s3 storages试图访问图像时,它将不起作用,所以我们要做的是只存储文件的密钥。在

文件的键是指向bucket中的映像的路径。E、 g,对于urlhttps://s3-eu-west-1.amazonaws.com/bucket/uploads/imgs/Most-Famous-Felines-034.jpguploads/imgs/Most-Famous-Felines-034.jpg,因此这是我们需要存储在模型中的值。在我的例子中,我使用这个片段从url中提取密钥:

^{pr2}$

一旦我做了这些改变,它就无缝地工作了。 我希望这对任何处于同样情况的人都有帮助。在

相关问题 更多 >