Skip to main content
 首页 » 编程设计

python之Django 应用程序不从 AWS 存储桶的媒体文件夹加载图像

2024年09月03日31lvdongjie

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

在我的网站上,当我将图片上传到产品时,它会以正确的路径上传到我的 aws s3 存储桶,但在很短的时间后,路径会从 https://mybucketname.s3.amazonaws 更改.com/media/cache/..../image.jpg 到 https://mybucketname.s3.amazonaws.com/cache/..../image.jpg

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

我在 heroku 上托管我的网络应用程序,静态文件提供正确但问题发生在媒体文件夹中。

这是我的代码-

utils.py文件

from storages.backends.s3boto3 import S3Boto3Storage 
 
StaticRootS3BotoStorage = lambda: S3Boto3Storage(location='static') 
MediaRootS3BotoStorage  = lambda: S3Boto3Storage(location='media') 

因为 static 和 media 是我的 s3 存储桶上的文件夹

配置文件

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 * 

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

请您参考如下方法:

为您的 Django 应用程序配置的文件存储系统应该是一个实现了 django.core.files.storage.Storage 的类。 [1]

storages.backends.s3boto3.S3Boto3Storage已经实现了这个存储接口(interface)。 [2]

设置StaticRootS3BotoStorage在utils.py到 lambda , Storage系统使用适当的 location 延迟实例化值(value);但是location存储类本身的属性永远不会改变。 [3]

location = setting('AWS_LOCATION', '') 

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

这种情况可以通过子类化storages.backends.s3boto3.S3Boto3Storage来解决反而。这保证了 location无论项目设置如何更改,该值都不会更改。

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