2013-03-20 4 views
16

Я использую django-compressor, чтобы объединить и сжать мои файлы CSS и JS на this site. Я обслуживаю статические файлы из ведра S3.django-compressor не устанавливает абсолютные пути изображения CSS на Heroku

На моей местной копии сайта, используя другой ведро S3, все это работает отлично. Но на реальном сайте, размещенном на Heroku, все работает кроме относительные URL-адреса для изображений в файлах CSS не переписываются.

например, эта строка в файле CSS:

background-image: url("../img/glyphicons-halflings-grey.png"); 

получает переписан:

background-image:url('https://my-dev-bucket-name.s3.amazonaws.com/static/img/glyphicons-halflings-grey.png') 

на моем сайте разработки, но не затрагивали живой сайт. Таким образом, сайт в реальном времени заканчивается поиском в pepysdiary.s3.amazonaws.com/static/CACHE/img/ для изображений (так как это относительно нового сжатого файла CSS).

На данный момент я поместил каталог в это место, содержащее изображения, но я не могу понять, почему существует эта разница. Оба места имеют это в настройках:

COMPRESS_CSS_FILTERS = [ 
    # Creates absolute urls from relative ones. 
    'compressor.filters.css_default.CssAbsoluteFilter', 
    # CSS minimizer. 
    'compressor.filters.cssmin.CSSMinFilter' 
] 

И CSS файлы минимизируются просто отлично ... но это как другой фильтр не применяется на живом сайте.

+0

FWIW, я отказался от этого. Не удалось решить проблему, а затем CSS и JS-файлы Compressor, сгенерированные на S3, возвращали 403 Forbidden errors. Жизнь слишком коротка. –

ответ

20

Недавно я столкнулся с этой проблемой на геройку, и запуск последней версии django-compressor (1.3) не решает проблему. Я предоставлю решение, которое я использую, а также объяснение проблем, с которыми я столкнулся.

Раствор

Я создал свой собственный «CssAbsoluteFilter», который удаляет проверку settings.DEBUG от метода «найти», как это:

# compress_filters.py 
from compressor.filters.css_default import CssAbsoluteFilter 
from compressor.utils import staticfiles 


class CustomCssAbsoluteFilter(CssAbsoluteFilter): 
    def find(self, basename): 
     # The line below is the original line. I removed settings.DEBUG. 
     # if settings.DEBUG and basename and staticfiles.finders: 
     if basename and staticfiles.finders: 
      return staticfiles.finders.find(basename) 

# settings.py 
COMPRESS_CSS_FILTERS = [ 
# 'compressor.filters.css_default.CssAbsoluteFilter', 
'app.compress_filters.CustomCssAbsoluteFilter', 
'compressor.filters.cssmin.CSSMinFilter', 
] 

Абсолютные URLs теперь всегда работает для меня будь то DEBUG = True или False.

Проблема

Вопрос связан с «compressor.filters.css_default.CssAbsoluteFilter», вашей настройки DEBUG, а также тот факт, что Heroku имеет файловую систему только для чтения и переписывает приложение файлы каждый раз, когда вы развертываете.

Причина, по которой компрессор работает правильно на вашем сервере разработки, заключается в том, что CssAbsoluteFilter всегда будет находить ваши статические файлы, когда DEBUG = True, даже если вы никогда не запускаете «collectstatic». Он ищет их в STATICFILES_DIRS.

Когда DEBUG = False на вашем производственном сервере, CssAbsoluteFilter предполагает, что статические файлы уже собраны в ваш COMPRESS_ROOT и не будут применять абсолютный фильтр, если он не сможет найти файлы.

Jerdez, автор Джанго-компрессора, explains it like this:

CssAbsoluteFilter работает с DEBUG = False, если вы успешно при условии, что файлы для работы с. Во время разработки компрессоры используют статический поиск файлов как удобство, поэтому вам не нужно постоянно запускать коллекцию.

Теперь для героику. Несмотря на то, что вы сохраняете свои статические файлы на S3, вам также необходимо сохранить их на heroku (using CachedS3BotoStorage). Поскольку heroku является файловой системой только для чтения, единственный способ сделать это - позволить героку автоматически собирать ваши статические файлы во время развертывания (см. https://devcenter.heroku.com/articles/django-assets).

По моему опыту, запуск «heroku run python manage.py collectstatic --noinput» вручную или даже в вашем Procfile будет загружать файлы на S3, но он НЕ будет сохранять файлы в вашем каталоге STATIC_ROOT (какой компрессор использует по умолчанию - COMPRESS_ROOT). Вы можете подтвердить, что ваши статические файлы были собраны на герою, используя 'heroku run ls path/to/gather'.

Если ваши файлы были собраны на heroku успешно, вы также сможете сжать ваши файлы без решения, указанного выше.

Однако, похоже, герой будет собирать только статические файлы, если вы внесли изменения в свои статические файлы с момента последнего развертывания. Если в ваши статические файлы не были внесены изменения, вы увидите что-то вроде «0 из 250 статических файлов, скопированных». Это проблема, потому что heroku полностью заменяет ваше содержимое приложения при развертывании, поэтому вы теряете все статические файлы, которые ранее были собраны в COMPRESS_ROOT/STATIC_ROOT. Если вы попытаетесь сжать ваши файлы после того, как собранные файлы больше не существуют на heroku, а DEBUG = False, CssAbsoluteFilter не заменит относительные URL-адреса абсолютными URL-адресами.

Мое решение выше позволяет избежать проблемы герой в целом и заменяет относительные URL-адреса css абсолютными URL-адресами, даже когда DEBUG = False.

Надеемся, другие люди также найдут эту информацию полезной.

+0

Хотел бы я найти это 3 дня назад. :) Я помещаю collectstatic и сжимаю вызовы в bin/post_compile и heroku config: set DISABLE_COLLECTSTATIC = 0 – derek73

+0

Это также объясняет, почему это сработало в первый раз, когда я развернул, но потом проиграл каждый раз после этого. Спасибо за подробное объяснение. – derek73

+0

для тех, кто использует sass, это и 'COMPRESS_PRECOMPILERS' с' ('text/x-scss', 'django_libsass.SassCompiler') 'решил мои проблемы – fjsj

0

У меня была эта точно такая же проблема уже месяц, но это фиксируется в выпуске 1.3 (3/18/13, так что вы, вероятно, были на 1.2), так что просто обновление:

pip install -U django-compressor 

Точная проблема, которую я отказался от разработки, но она связана с тем, что Heroku и CssAbsoluteFilter вызываются, но не работают при методе _converter. Глядя на список изменений 1.3, единственное связанное с ним совершение: https://github.com/jezdez/django_compressor/commit/8254f8d707f517ab154ad0d6d77dfc1ac292bf41

Я сдался, жизнь слишком короткая.

+0

Интересно, спасибо юаньма! Так вы пробовали 1.3, и это исправляет проблему для вас? Я не вижу, как эта конкретная фиксация будет исправлять вещи, но я могу ошибаться, или там может быть что-то еще, что делает работу. –

+0

Модернизация до 1.3 не работала для меня. См. Мое решение: http://stackoverflow.com/a/17033883/387337 –

0

Тем временем это было исправлено в django-compressor 1.6. От changelog:

Apply CssAbsoluteFilter to precompiled css even when compression is disabled 

т.е. абсолютного фильтра запускается даже с DEBUG = True.

Смежные вопросы