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

时间:2015-07-31 17:23:38

标签: 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' isn't accessible via COMPRESS_URL ('/static/') and can't be compressed

  3. 不知道这里发生了什么。

    编辑:我之前的存储桶策略允许只读访问权限。也许这可能是我的压缩器无法在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 Configuration是:

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

2 个答案:

答案 0 :(得分:1)

我在自己的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)

答案 1 :(得分:0)

我认为您的staticmedia网址/根目录不正确。他们应该遵循以下格式:

MEDIA_URL = S3_URL + MEDIA_DIRECTORY
STATIC_URL = S3_URL + STATIC_DIRECTORY
MEDIA_ROOT = '/home/host/app/static_root/media'
STATIC_ROOT = '/home/host/app/static_root/static'

注意:将MEDIA_ROOTSTATIC_ROOT更改为项目的配置方式。

修改

对不起,没有看到你在使用压缩机。尝试执行以下操作:

COMPRESS_URL = S3_URL + STATIC_DIRECTORY
STATIC_URL = COMPRESS_URL
MEDIA_URL = S3_URL + MEDIA_DIRECTORY
MEDIA_ROOT = '/home/host/app/static_root/media'
STATIC_ROOT = '/home/host/app/static_root/static'