如何使用Amazon S3配置Django-Compressor和Django-Staticfiles?

29
我正在尝试设置django-compressordjango-staticfiles,以便压缩的CSS / Javascript和图像来自Amazon的S3。我已经成功地使用S3作为后端设置了静态文件,所以它的collectstatic命令会将文件发送到S3而不是STATIC_ROOT。然而,当我尝试将django-compressor添加到混合中时,一切似乎都会崩溃。遵循documentation关于设置远程存储的说明,我创建了一个存储后端子类boto,因此我复制了examplestorage.py中。一旦我开始使用这个缓存后端,文件被复制到static_media而不是S3。在第一次页面加载之后,CACHE文件夹出现在S3和static_media文件夹中。将STATICFILES_STORAGECOMPRESS_STORAGE设置回boto的正常S3类(storages.backends.s3boto.S3BotoStorage)会导致静态资源被收集到S3存储桶中,而没有static_media文件夹。但是,尝试重新加载页面会抛出错误:
Caught NotImplementedError while rendering: This backend doesn't support absolute paths.

使用标签{% compress css %},文件路径为compressor/base.py进行代码高亮。

settings.py中的部分:

DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
AWS_ACCESS_KEY_ID = 'key'
AWS_SECRET_ACCESS_KEY ='secret'
AWS_STORAGE_BUCKET_NAME = 'my-bucket'
S3_URL = 'http://my-bucket.s3.amazonaws.com/'

MEDIA_ROOT = 'client_media'
MEDIA_URL = '/media/'
STATIC_ROOT = 'static_media'
STATIC_URL = S3_URL
ADMIN_MEDIA_PREFIX = S3_URL + 'admin/'
STATICFILES_DIRS = (
    join(DIRNAME, 'static'),
)
STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
    'compressor.finders.CompressorFinder',
)

COMPRESS_ENABLED = True
COMPRESS_URL = S3_URL
COMPRESS_ROOT = STATIC_ROOT
COMPRESS_STORAGE = 'storage.CachedS3BotoStorage'
STATICFILES_STORAGE = COMPRESS_STORAGE

那么我哪里做错了?也许在使用CachedS3BotoStorage自定义存储时,我配置错误了吗?

4个回答

10

您的配置看起来是正确的。您应该保持STATICFILES_STORAGECOMPRESS_STORAGE都设置为storage.CachedS3BotoStorage,而不是切换回storages.backends.s3boto.S3BotoStorage

根据django-compressor issue,问题出在django-staticfiles在collectstatic过程中保存的方式(使用shutil.copy2)。这个问题已经在更新版本的django-staticfiles中得到了修复,可以使用它来替换Django 1.3附带的版本。

pip install django-staticfiles==dev

并且在你的 settings.py 文件中,切换到更新的版本:

STATICFILES_FINDERS = (
    #"django.contrib.staticfiles.finders.FileSystemFinder",
    #"django.contrib.staticfiles.finders.AppDirectoriesFinder",
    "staticfiles.finders.FileSystemFinder",
    "staticfiles.finders.AppDirectoriesFinder",
    "compressor.finders.CompressorFinder",
)

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    #'django.contrib.staticfiles',
    'staticfiles',
    #...
)
在再次运行python manage.py collectstatic后,来自django-compressor的CACHE目录和收集的静态文件应该都显示在S3上。

0
经过多天的努力和研究,我终于成功了,并决定写一篇详细指南,包括如何使用gzip压缩服务。
基本上你需要做以下几件事情:
  1. 使用AWS_IS_GZIPPED = True
  2. 如果你的S3在美国以外。你需要创建一个自定义的S3Connection类,其中你需要覆盖DefaultHost变量为你的S3 url。例如:s3-eu-west-1.amazonaws.com
  3. 如果你使用带点的bucket名称,例如subdomain.domain.tld。你需要设置AWS_S3_CALLING_FORMAT = 'boto.s3.connection.OrdinaryCallingFormat'
  4. 你必须在你的CachedS3BotoStorage中设置non_gzipped_file_content = content.file
这是你需要的CachedS3BotoStorage类:
class CachedS3BotoStorage(S3BotoStorage):
    """
    S3 storage backend that saves the files locally, too.
    """
    connection_class = EUConnection
    location = settings.STATICFILES_LOCATION
    def __init__(self, *args, **kwargs):
        super(CachedS3BotoStorage, self).__init__(*args, **kwargs)
        self.local_storage = get_storage_class(
            "compressor.storage.CompressorFileStorage")()

def save(self, name, content):
    non_gzipped_file_content = content.file
    name = super(CachedS3BotoStorage, self).save(name, content)
    content.file = non_gzipped_file_content
    self.local_storage._save(name, content)
    return name

请注意,EUConnection 是一个自定义类,在其中我将 DefaultHost 设置为我的 S3 位置。请查看更长且详细的指南以获取完整的自定义存储和 settings.py 配置信息。

0

0

我使用 django_compressor==1.2 解决了我的问题。不过我不确定为什么你需要安装 django-staticfiles,因为除了 1.2 版本以外的所有 django_compressor 版本都有这个问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接