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.py
file inside a Django app. I like to have core
app inside every Django project I start where I define such application wide logic, so in my case, the file's path is core/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.py
set STATICFILES_STORAGE
as ForgivingManifestStaticFilesStorage
:
STATICFILES_STORAGE = "core.storage.ForgivingManifestStaticFilesStorage"
Run python manage.py collecstatic
and 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 collecstatic
and never worry about missing static files.
Hey, if you've found this useful, please share the post to help other folks find it: