python - 无法使用 Django 从 S3 提供静态媒体

标签 python django amazon-web-services amazon-s3 boto

我需要使用 Amazon S3 为我的 Django 项目提供我的静态和媒体文件。

但是,我面临着很多问题。首先,我的代码:

s3utils.py

from storages.backends.s3boto import S3BotoStorage

class FixedS3BotoStorage(S3BotoStorage):
def url(self, name):
    url = super(FixedS3BotoStorage, self).url(name)
    if name.endswith('/') and not url.endswith('/'):
        url += '/'
    return url

StaticS3BotoStorage = lambda: FixedS3BotoStorage(location='static')
MediaS3BotoStorage = lambda: FixedS3BotoStorage(location='media')

settings.py

DEFAULT_FILE_STORAGE = 'SpareGuru.s3utils.MediaS3BotoStorage'
STATICFILES_STORAGE = 'SpareGuru.s3utils.StaticS3BotoStorage'

AWS_HOST = "s3-ap-southeast-1.amazonaws.com"
AWS_ACCESS_KEY_ID = 'xx'
AWS_SECRET_ACCESS_KEY = 'yy'
AWS_STORAGE_BUCKET_NAME = 'zz'

S3_URL = 'http://%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME
MEDIA_DIRECTORY = '/media/'
STATIC_DIRECTORY = '/static/'

STATIC_URL = "/static/"

MEDIA_URL = "/media/"

STATIC_ROOT = S3_URL + STATIC_DIRECTORY
COMPRESS_ROOT = STATIC_ROOT
MEDIA_ROOT = S3_URL + MEDIA_DIRECTORY

以下是我面临的问题:

  1. 当运行 ./manage.py collectstatic 时,它开始将文件上传到 S3,在几个文件之后,我收到了 Broken Pipe 错误。

  2. 尝试运行该网页时,出现错误:'https://zz.s3.amazonaws.com/static/css/bootstrap.min.css?Signature=sign&Expires=1438359937&AWSAccessKeyId= xx' 无法通过 COMPRESS_URL ('/static/') 访问,也无法压缩

不知道这里发生了什么。

编辑:我之前的存储桶策略允许只读访问。所以这可能是我的压缩器无法在 S3 上创建文件的原因。我已经更新了政策,但仍然无效。更新后的政策是:

{
"Statement": [
    {
        "Sid": "PublicReadForGetBucketObjects",
        "Effect": "Allow",
        "Principal": {
            "AWS": "*"
        },
        "Action": [
            "s3:GetObject"
        ],
        "Resource": [
            "arn:aws:s3:::zz/*"
        ]
    },
    {
        "Action": "s3:*",
        "Effect": "Allow",
        "Resource": [
            "arn:aws:s3:::zz",
            "arn:aws:s3:::zz/*"
        ],
        "Principal": {
            "AWS": [
                "my-arn:/goes=here"
            ]
        }
    }
]
}

我的存储桶的 CORS 配置是:

<CORSConfiguration>
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Authorization</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

最佳答案

我在我自己的 Django 项目上运行它。我去检查了差异。您可能会尝试的一件事是添加:

AWS_QUERYSTRING_AUTH = False

到你的settings.py。这至少可以帮助您解决问题 #2。

这是我的 settings.py 中的完整示例。注意:我不将 S3 用于静态文件,仅用于媒体。

from boto.s3.connection import SubdomainCallingFormat
AWS_CALLING_FORMAT = SubdomainCallingFormat()
DEFAULT_FILE_STORAGE = 'project.s3utils.MediaRootS3BotoStorage'
AWS_ACCESS_KEY_ID = os.getenv('AWS_ACCESS_KEY_ID', None)
AWS_SECRET_ACCESS_KEY = os.getenv('AWS_SECRET_KEY', None)
AWS_SECRET_KEY = os.getenv('AWS_SECRET_KEY')
AWS_STORAGE_BUCKET_NAME = os.getenv('AWS_STORAGE_BUCKET_NAME')
AWS_QUERYSTRING_AUTH = False
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.StaticFilesStorage'
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, '../',  'static')
MEDIA_ROOT = os.path.join(BASE_DIR, '../..',  'media')
MEDIA_URL = 'http://{!s}.s3.amazonaws.com/media/'.format(AWS_STORAGE_BUCKET_NAME)

关于python - 无法使用 Django 从 S3 提供静态媒体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31751818/

相关文章:

python - 获取列表的所有组合(笛卡尔积)的最佳方法是什么?

python - 对分页、django 内的记录进行计算

python - Django 根据另一个查询注释查询集

django - 迭代字段时访问 django 表单的初始值

django - 亚马逊联盟API

java - DynamoDbMapper ScanExpression 无法映射到 Java 对象

python - Pandas python 用字符串替换空行

python - 有没有办法在 python 脚本中嵌入依赖项?

python - Django 线程评论系统

ios - CloudFront 和 S3 的端点问题