In Django 3.0, CachedStaticFilesStorage was removed, in favor of ManifestStaticFilesStorage. Both are designed to hash collected files, resulting in a <filename>.<hash>.<ext> file that can be set to infinite expiration.

CachedStaticFilesStorage was deprecated in Django 2.1, and for some fairly reasonable reasons:

  1. It could sometimes result in multiple hashed files for the same source file (in the event that CSS file A includes B includes A).
  2. Finding the right hash for a file required first computing a hash from a source file, which is not optimal (though these were cached in memcached, which helped).

ManifestStaticFilesStorage solves this for most people by:

  1. Only ever computing hashes once, at collectfiles time.
  2. Storing (and then looking up) all hashes in a staticfiles.json.

The Problem

The problem is that this only looks for this file in one place: /static/ (or, technically, settings.STATIC_ROOT). The expectation is that all static media for the entire project is built once, and never changes. Fine for typical usage, but not fine when extensions are involved.

This means it's not suitable for Review Board.

Solutions

To deal with this, we'll need to introduce one of three new storage classes:

  1. One that can look for staticfiles.json in more than one location (by, say, providing a map of path prefixes to location roots)