django-compressor没有在Heroku上设置绝对CSS图像路径

时间:2013-03-20 19:02:25

标签: django amazon-s3 django-compressor

我正在使用django-compressorthis site上连接和压缩我的CSS和JS文件。我正在从S3存储桶提供静态文件。

在我的本地网站副本上,使用不同的S3存储桶,这一切都很完美。但是在Heroku上托管的实时网站上,除了之外,所有内容都在上工作,CSS文件中图像的相对URL不会被重写。

例如,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文件正在最小化......但它就像其他过滤器没有在现场网站上应用。

3 个答案:

答案 0 :(得分:20)

我最近在heroku上遇到了这个问题,运行最新版本的django-compressor(1.3)并没有解决问题。我将提供我正在使用的解决方案,以及我在此过程中遇到的问题的解释。

解决方案

我创建了自己的'CssAbsoluteFilter',它从'find'方法中删除了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',
]

绝对网址现在总是适用于我,无论DEBUG = True还是False。

问题

该问题与'compressor.filters.css_default.CssAbsoluteFilter',您的DEBUG设置以及heroku具有只读文件系统以及每次部署时覆盖您的应用程序文件这一事实有关。

压缩在开发服务器上正常工作的原因是因为当DEBUG = True时,CssAbsoluteFilter将始终找到您的静态文件,即使您从未运行'collectstatic'。它在STATICFILES_DIRS中查找它们。

当生产服务器上的DEBUG = False时,CssAbsoluteFilter会假定静态文件已经收集到您的COMPRESS_ROOT中,如果无法找到文件,则不会应用绝对过滤器。

Jerdez,django-compressor的作者,explains it like this

  

如果您已成功提供要使用的文件,则CssAbsoluteFilter与DEBUG = False一起使用。在开发过程中,压缩器使用staticfiles finder作为方便,因此您不必一直运行collectstatic。

现在为heroku。即使您将静态文件存储在S3上,也需要将它们存储在heroku(using CachedS3BotoStorage)上。由于heroku是一个只读文件系统,唯一的方法是让heroku在部署期间自动收集静态文件(参见https://devcenter.heroku.com/articles/django-assets)。

根据我的经验,手动或甚至在Procfile中运行'heroku run python manage.py collectstatic --noinput'会将文件上传到S3,但它不会将文件保存到STATIC_ROOT目录(默认情况下压缩器使用)作为COMPRESS_ROOT)。您可以使用'heroku run ls path / to / collecting'确认您的静态文件已经在heroku上收集。

如果您的文件已成功收集在heroku上,您应该能够成功压缩文件,而无需我上面提供的解决方案。

但是,如果您自上次部署以来对静态文件进行了更改,那么heroku似乎只会收集静态文件。如果没有对静态文件进行任何更改,您将看到“复制了250个静态文件中的0个”。这是一个问题,因为heroku在部署时会完全替换您的应用程序内容,因此您将丢失以前在COMPRESS_ROOT / STATIC_ROOT中收集的任何静态文件。如果在heroku上不再存在收集的文件且DEBUG = False后尝试压缩文件,则CssAbsoluteFilter不会用绝对URL替换相对URL。

我上面的解决方案完全避免了heroku问题,并且即使在DEBUG = False时也用绝对URL替换相对的css url。

希望其他人也会发现这些信息也很有用。

答案 1 :(得分:0)

我现在已经有一个月完全相同的问题,但这在1.3版本中已经修复(2013年3月18日,所以你可能在1.2上),所以只需升级:

pip install -U django-compressor

我放弃了解决的确切问题,但它与Heroku和CssAbsoluteFilter有关,但在_converter方法失败了。查看1.3更改日志,唯一相关的提交是:https://github.com/jezdez/django_compressor/commit/8254f8d707f517ab154ad0d6d77dfc1ac292bf41

我放弃了,生命太短暂了。

答案 2 :(得分:0)

同时这已在django-compressor 1.6中得到修复。来自changelog

Apply CssAbsoluteFilter to precompiled css even when compression is disabled

即。即使使用DEBUG = True,也会运行绝对过滤器。