Static Files Versioning in Django

Installation

It is pretty easy in 2.2+, just add to your settings:

STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'

Don’t forget to set:

DEBUG = False

And do collectstatic. This way Django will run over all of your files and search for them in your statics directory.

ValueError: the file <file_path> could not be found

Be careful with urls – they might work on the website, but it the storage module may not identify the paths correctly. This error occurs:

ValueError: The file 'css/plugins/fonts/fontawesome-webfont.eot' could not be found with <django.contrib.staticfiles.storage.ManifestStaticFilesStorage object at 0x12ae4e220>.

Because it has a path like this

fonts/fontawesome-webfont.eot

You need to make it relative:

../../fonts/fontawesome-webfont.eot

RuntimeError: Max post-process passes exceeded.

If you see an error like this:

Post-processing 'All' failed!
RuntimeError: Max post-process passes exceeded.

Then check your @import statements – remove the commented once and try to find where the import is circular.

Conclusion

Versioning does not tolerate uncarefully made static files. You may spend a few hours removing rudimental imports, files, altering paths, removing urls to non-existent files. That’s totally normal.

Celery – schedule tasks with pauses between them

I needed to schedule 10 tasks that have these conditions

  1. A time gap between tasks is fixed (but varies)
  2. No need to pass results of one task to another
  3. Need to read a database in every task (important: at the moment of the execution)

I tried a few options, and this one worked

 ret = chain(task1.si(args).set(countdown=30*1), ..., task10.si(args).set(countdown=30*10)).apply_sync()

Important note – the signature here is not .s() but .si() this way you don’t pass the result of task1 to task2. You set the countdown with set() and not inside the apply_sync().

It is simple but it took me some time to figure out.