我最近在 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 中,如果找不到文件,则不会应用绝对过滤器。
Jerdez,django-compressor 的作者,explains it like this:
如果您已成功提供要使用的文件,则 CssAbsoluteFilter 与 DEBUG = False 一起使用。在开发过程中,为了方便起见,压缩器使用静态文件查找器,因此您不必一直运行 collectstatic。
现在是heroku。即使您将静态文件存储在 S3 上,您也需要将它们存储在 heroku (using 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 时也将相对 css url 替换为绝对 url。
希望其他人也会发现此信息对您有所帮助。