Make Django's collectstatic command forgiving
Jan 29, 2019 · Updated: Jul 12, 2021 · by Tim Kamanin
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!
-
Create a
storage.pyfile inside a Django app. I like to havecoreapp inside every Django project I start where I define such application wide logic, so in my case, the file's path iscore/storage.py. -
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 file is missing, let's forgive and ignore that. result = name return result -
In
setting.pysetSTATICFILES_STORAGEasForgivingManifestStaticFilesStorage:STATICFILES_STORAGE = "core.storage.ForgivingManifestStaticFilesStorage" -
Run
python manage.py collecstaticand see how nicely it finished!
Done!
UPDATE:
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
settings.py:STATICFILES_STORAGE = ( "django_forgiving_collecstatic.storages.ForgivingManifestStaticFilesStorage" ) -
Run
python manage.py collecstaticand never worry about missing static files.
Hey, if you've found this useful, please share the post to help other folks find it: