Django应用程序不会从AWS Bucket的媒体文件夹加载图像

时间:2018-12-20 22:32:07

标签: python django amazon-s3 django-oscar django-storage

我正在使用django-oscar,并希望通过AWS S3提供我的静态文件。 为了配置s3存储桶,我创建了一个名为aws的模块,其中包含conf.pyutils.py文件。

在我的网站上,当我将图像上传到产品时,它以正确的路径上传到了我的aws s3存储桶,但是很快,该路径从https://mybucketname.s3.amazonaws.com/media/cache/..../image.jpg变为https://mybucketname.s3.amazonaws.com/cache/..../image.jpg < / p>

图像位于我的存储桶中的media文件夹中。

我将我的Web应用托管在heroku上,静态文件可以正确提供,但问题出在媒体文件夹中。

这是我的代码-

utils.py文件

from storages.backends.s3boto3 import S3Boto3Storage

StaticRootS3BotoStorage = lambda: S3Boto3Storage(location='static')
MediaRootS3BotoStorage  = lambda: S3Boto3Storage(location='media')

staticmedia是我的s3存储桶上的文件夹

conf.py

import datetime

AWS_ACCESS_KEY_ID = "xxx"
AWS_SECRET_ACCESS_KEY = "yyy"

AWS_PRELOAD_METADATA = True
AWS_QUERYSTRING_AUTH = False
AWS_DEFAULT_ACL = None 

DEFAULT_FILE_STORAGE = 
'myproject.aws.utils.MediaRootS3BotoStorage'
STATICFILES_STORAGE = 
'myproject.aws.utils.StaticRootS3BotoStorage'
AWS_STORAGE_BUCKET_NAME = 'mybucket-name'
S3DIRECT_REGION = 'us-east-2'
S3_URL = '//%s.s3.amazonaws.com/' % AWS_STORAGE_BUCKET_NAME
MEDIA_URL = '//%s.s3.amazonaws.com/media/' % AWS_STORAGE_BUCKET_NAME
MEDIA_ROOT = MEDIA_URL
STATIC_URL = S3_URL + 'static/'
ADMIN_MEDIA_PREFIX = STATIC_URL + 'admin/'

two_months = datetime.timedelta(days=61)
date_two_months_later = datetime.date.today() + two_months
expires = date_two_months_later.strftime("%A, %d %B %Y 20:00:00 
GMT")

AWS_HEADERS = { 
    'Expires': expires,
    'Cache-Control': 'max-age=%d' % 
    (int(two_months.total_seconds()), ),
}

和我的settings.py我添加了这个

from myproject.aws.conf import *

我应该怎么做才能解决此问题?

1 个答案:

答案 0 :(得分:2)

为Django应用配置的文件存储系统应为实现django.core.files.storage.Storage [1]

的类

storages.backends.s3boto3.S3Boto3Storage已实现此存储接口。 [2]

StaticRootS3BotoStorage中的utils.py设置为lambdaStorage系统将使用适当的location值进行延迟实例化;但是存储类本身中的location属性永远不会改变。 [3]

location = setting('AWS_LOCATION', '')

当项目设置更改时,Django清除存储实例的属性。 [4] 因此,在存储系统上解析location属性时,它可以有效地查找类属性1(上面的代码段显示location值)因为实例中缺少location属性。

可以通过子类storages.backends.s3boto3.S3Boto3Storage来解决这种情况。这样可以保证location的值永远不会改变,而与项目设置的改变无关。

class StaticRootS3BotoStorage(S3Boto3Storage):
    location = 'static'

class MediaRootS3BotoStorage(S3Boto3Storage):
    location = 'media'