django amazon-s3 django-compressor

django-compressor no establece rutas de imagen de CSS absolutas en Heroku



amazon-s3 (3)

He tenido este mismo problema durante un mes, pero esto se solucionó en la versión 1.3 (18/3/13, por lo que probablemente estabas en la versión 1.2), así que simplemente actualiza:

pip install -U django-compressor

El problema exacto al que renuncié a hacer ejercicio, pero está relacionado con Heroku y CssAbsoluteFilter que se llaman, pero fallan en el método _converter. En cuanto al registro de cambios 1.3, el único compromiso relacionado es este: https://github.com/jezdez/django_compressor/commit/8254f8d707f517ab154ad0d6d77dfc1ac292bf41

Me rendí allí, la vida es demasiado corta.

Estoy usando django-compressor para concatenar y comprimir mis archivos CSS y JS en este sitio . Estoy sirviendo archivos estáticos de un cubo S3.

En mi copia local del sitio, utilizando un cubo S3 diferente, todo esto funciona perfectamente. Pero en el sitio en vivo, alojado en Heroku, todo funciona excepto las URL relativas para las imágenes en los archivos CSS que no se vuelven a escribir.

Por ejemplo, esta línea en el archivo CSS:

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

se reescribe a

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

en mi sitio de desarrollo, pero no se toca en el sitio en vivo. Entonces, el sitio en vivo termina buscando en las imágenes pepysdiary.s3.amazonaws.com/static/CACHE/img/ (en relación con el nuevo archivo CSS comprimido).

Por ahora, he puesto un directorio en esa ubicación que contiene las imágenes, pero no puedo entender por qué hay esta diferencia. Ambos sitios tienen esto en su configuración:

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

Y los archivos CSS se están minimizando muy bien ... pero es como si el otro filtro no se aplicara en el sitio activo.


Mientras tanto esto se ha corregido en django-compressor 1.6. Desde el changelog :

Apply CssAbsoluteFilter to precompiled css even when compression is disabled

Es decir, el filtro absoluto se ejecuta incluso con DEBUG = True.


Recientemente me encontré con este problema en heroku, y ejecutar la última versión de django-compressor (1.3) no resuelve el problema. Proporcionaré la solución que estoy usando, así como una explicación de los problemas que encontré en el camino.

La solución

Creé mi propio ''CssAbsoluteFilter'' que elimina la comprobación de settingsBBUG del método ''buscar'' de esta manera:

# 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'', ]

Las direcciones URL absolutas ahora siempre funcionan para mí, ya sea DEBUG = True o False.

El problema

El problema está relacionado con ''compressor.filters.css_default.CssAbsoluteFilter'', su configuración DEBUG y el hecho de que heroku tiene un sistema de archivos de solo lectura y sobrescribe los archivos de su aplicación cada vez que lo implementa.

La razón por la que comprimir funciona correctamente en su servidor de desarrollo es porque CssAbsoluteFilter siempre encontrará sus archivos estáticos cuando DEBUG = Verdadero, incluso si nunca ejecuta ''collectstatic''. Los busca en STATICFILES_DIRS.

Cuando DEBUG = False en su servidor de producción, CssAbsoluteFilter asume que los archivos estáticos ya se han recopilado en su COMPRESS_ROOT y no aplicará el filtro absoluto si no puede encontrar los archivos.

Jerdez, autor de django-compressor, lo explica así :

CssAbsoluteFilter funciona con DEBUG = False si ha proporcionado correctamente los archivos para trabajar. Durante el desarrollo, los compresores utilizan el buscador de archivos estáticos como una conveniencia para que no tenga que ejecutar la recopilación estática todo el tiempo.

Ahora para heroku. Aunque esté almacenando sus archivos estáticos en S3, también debe almacenarlos en heroku ( utilizando CachedS3BotoStorage ). Dado que heroku es un sistema de archivos de solo lectura, la única forma de hacerlo es dejar que heroku recopile sus archivos estáticos automáticamente durante la implementación (consulte https://devcenter.heroku.com/articles/django-assets ).

En mi experiencia, ejecutar ''heroku run python manage.py collectstatic --noinput'' manualmente o incluso en su Procfile cargará los archivos a S3, pero NO los guardará en su directorio STATIC_ROOT (que el compresor utiliza de forma predeterminada como COMPRESS_ROOT ). Puede confirmar que sus archivos estáticos se han recopilado en heroku utilizando ''heroku run ls path / to / recoger''.

Si sus archivos se han recopilado en heroku con éxito, también debería poder comprimirlos con éxito, sin la solución que le proporcioné anteriormente.

Sin embargo, parece que heroku solo recopilará archivos estáticos si ha realizado cambios en sus archivos estáticos desde su último despliegue. Si no se han realizado cambios en sus archivos estáticos, verá algo como "0 de 250 archivos estáticos copiados". Esto es un problema porque heroku reemplaza completamente el contenido de su aplicación cuando lo implementa, por lo que pierde los archivos estáticos que se recopilaron previamente en COMPRESS_ROOT / STATIC_ROOT. Si intenta comprimir sus archivos después de que los archivos recopilados ya no existan en heroku y DEBUG = False, el CssAbsoluteFilter no reemplazará las URL relativas con URL absolutas.

Mi solución anterior evita el problema del heroku por completo, y reemplaza las URL de css relativas con las URL absolutas, incluso cuando DEBUG = False.

Esperemos que otras personas encuentren esta información útil también.