Make Django's collectstatic command forgiving29 Jan · by Tim Kamanin · 3 min read
Have this ever happened to you? You run a
python manage.py collecstatic command, it progresses for some time and then throws an error, something like:
ValueError: The file 'theme/startup/css/font/ytp-regular.eot' could not be found with <django.contrib.staticfiles.storage.ManifestStaticFilesStorage object at 0x10b47cc50>
Well, that means, your staticfiles storage collector couldn't find a file declared somewhere deep in CSS. Sometimes this error is a piece of useful information, but sometimes, it's a guaranteed pain, especially if you use some third-party themes, jquery plugins or as in my case, the Startup framework.
Okay, so now what? If you know that the file is essential you go and fix that missing part, but if you don't care and want the static collector to advance and ignore that missing file?
Well, you need The Forgiving Static Files Storage.
And here's how to make one. By default, in your settings.py
STATICFILES_STORAGE is set to
django.contrib.staticfiles.storage.ManifestStaticFilesStorage and it's the class that's responsible for our
python manage.py collecstatic behavior.
Thus we could extend it and tell it to ignore missing files. Let's do this!
storage.pyfile inside a Django app. I like to have
coreapp inside every Django project I start where I define such application wide logic, so in my case, the file's path is
Add the following contents to a file:
from django.contrib.staticfiles.storage import ManifestStaticFilesStorage class ForgivingManifestStaticFilesStorage(ManifestStaticFilesStorage): def hashed_name(self, name, content=None, filename=None): try: result = super().hashed_name(name, content, filename) except ValueError: # When the fille is missing, let's forgive and ignore that. result = name return result
STATICFILES_STORAGE = 'core.storage.ForgivingManifestStaticFilesStorage'
python manage.py collecstaticand see how nicely it finished!
I've created a PyPI package based on this tutorial. The package is called django-forgiving-collectstatic and here's how to use it:
Install from PyPI:
pip install django-forgiving-collectstatic
Set in your
STATICFILES_STORAGE = 'django_forgiving_collecstatic.storages.ForgivingManifestStaticFilesStorage'
python manage.py collecstaticand never worry about missing static files.