16

我正在使用django-compressor在这个站点上连接和压缩我的 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 文件被最小化得很好......但就像其他过滤器没有被应用在实时站点上一样。

4

3 回答 3

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,绝对 url 现在总是对我有用。

问题

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

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

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

django-compressor 的作者 Jerdez是这样解释的:

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

现在对于heroku。即使您将静态文件存储在 S3 上,也需要将它们存储在 heroku 上(使用 CachedS3BotoStorage)。由于 heroku 是一个只读文件系统,唯一的方法是让 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/collected”确认您的静态文件已在 heroku 上收集。

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

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

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

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

于 2013-06-10T22:31:42.143 回答
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

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

于 2013-03-24T14:26:43.263 回答
0

同时,这已在 django-compressor 1.6 中得到修复。从变更日志

Apply CssAbsoluteFilter to precompiled css even when compression is disabled

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

于 2015-12-06T16:12:14.750 回答