Подтвердить что ты не робот

Как настроить django-compressor и django-staticfiles с помощью Amazon S3?

Я пытаюсь настроить django-compressor и django-staticfiles, чтобы сжатый CSS/Javascript и изображения подаются с Amazon S3.

Мне удалось установить staticfiles, используя S3 в качестве бэкэнд, поэтому команда collectstatic отправляет файлы на S3 вместо STATIC_ROOT.

Однако при попытке добавить django-compressor в микс, где все это, кажется, разваливается для меня. После документации по настройке удаленных хранилищ я создал подкласс бэкэнда хранилища, boto, поэтому я скопировал пример в storage.py. Как только я начну использовать этот кэшированный бэкэнд, файлы копируются в static_media, а не S3. После загрузки первой страницы папка CACHE появляется на S3 и в папке static_media.

Настройка STATICFILES_STORAGE и COMPRESS_STORAGE назад к нормальному классу S3 (storages.backends.s3boto.S3BotoStorage) приводит к тому, что статические активы собираются в ведро S3 и не имеют папки static_media. Однако попытка перезагрузки страницы выдает ошибку:

Caught NotImplementedError while rendering: This backend doesn't support absolute paths.

выделение {% compress css %} в качестве тега и compressor/base.py в качестве источника.

Секция s3/staticfiles/compressor моего 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 пользовательского хранилища?

4b9b3361

Ответ 1

Ваши настройки выглядят правильно. Вы должны сохранить как STATICFILES_STORAGE, так и COMPRESS_STORAGE на storage.CachedS3BotoStorage, но не вернуться к storages.backends.s3boto.S3BotoStorage.

В соответствии с этой проблемой django-compressor проблема связана с тем, как django-staticfiles сохраняет в процессе сбора данных (используя 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 на S3 будет отображаться как каталог CACHE из django-compressor, так и собранные файлы статических файлов.

Ответ 2

Использование django_compressor==1.2 работало для меня. Я не уверен, почему вам нужно установить django-staticfiles, но все версии django_compressor except 1.2 имеют эту проблему.

Ответ 3

После многих дней напряженной работы и исследований я наконец смог это сделать, и я решил написать подробное руководство об этом, в том числе как также обслуживать их zip с помощью gzip.

В основном вам нужно сделать несколько вещей:

  • Используйте AWS_IS_GZIPPED = True
  • Если ваш S3 находится за пределами США. Вам нужно создать пользовательский класс S3Connection, где вы переопределите переменную DefaultHost на свой S3-url. Пример s3-eu-west-1.amazonaws.com
  • Если вы используете точечное имя ведра, пример subdomain.domain.tld. Вам нужно установить AWS_S3_CALLING_FORMAT = 'boto.s3.connection.OrdinaryCallingFormat'
  • Вы должны установить non_gzipped_file_content = content.file в свой CachedS3BotoStorage

Это класс 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

Ответ 4

Попробуйте это сообщение, которое завершит вышеуказанное решение с некоторыми строками, чтобы исправить проблему, которая создает много (кратных) манифестов _%. json в Amazon S3. fooobar.com/info/192502/...