skip to content

In Django 6.1, how do you configure ManifestStaticFilesStorage in settings, and what happened to the STATICFILES_STORAGE setting?

level: juniorimportance: should knowfreq 40%

answer

  1. one dictionary of named storages
  2. two aliases Django itself uses
  3. BACKEND plus optional OPTIONS
  4. your value is not merged
  5. the old setting went in 5.1

basics

~10 s

Set STORAGES['staticfiles']['BACKEND'] to 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage' and keep a 'default' entry, because STORAGES replaces the built-in value wholesale. STATICFILES_STORAGE was deprecated in Django 4.2 and removed in 5.1.

solid answer

~40 s

Django 4.2 introduced the `STORAGES` setting: a dictionary mapping aliases to a `BACKEND` dotted path and optional `OPTIONS`, which are passed to the backend's constructor as keyword arguments. Two aliases matter to Django itself: `default` for uploaded files and `staticfiles` for collected static files. To hash static files you set the `staticfiles` backend to `django.contrib.staticfiles.storage.ManifestStaticFilesStorage`. Your `STORAGES` value is not merged with the default, so if you define only `staticfiles` the `default` alias disappears and the first file save raises `InvalidStorageError`; a missing `staticfiles` alias is caught earlier by the system check `staticfiles.E005`. `STATICFILES_STORAGE` and `DEFAULT_FILE_STORAGE` were deprecated in 4.2 and removed in 5.1. Tweaks such as `manifest_strict` are class attributes, so they are set by subclassing, not through `OPTIONS`.

code

python · 14 lines
python
from django.contrib.staticfiles.storage import ManifestStaticFilesStorage


class ProjectManifestStorage(ManifestStaticFilesStorage):
    # Class attributes, not constructor arguments: not accepted in OPTIONS.
    manifest_name = 'assets-manifest.json'
    max_post_process_passes = 10


# settings.py
STORAGES = {
    'default': {'BACKEND': 'django.core.files.storage.FileSystemStorage'},
    'staticfiles': {'BACKEND': 'config.storage.ProjectManifestStorage'},
}

go deeper

for a junior

Recall the STORAGES shape, the two special aliases default and staticfiles, and the dotted path of ManifestStaticFilesStorage.

for a middle

Explain that STORAGES is not merged with the default, what OPTIONS are passed to, and why class attributes need a subclass.

for a senior

Audit upgraded projects for leftover STATICFILES_STORAGE or DEFAULT_FILE_STORAGE lines and for settings modules that drop an alias.

for a principal

Set a convention for per-environment storage settings, such as spreading a base STORAGES dictionary, so aliases cannot vanish between environments.

## The STORAGES setting Since Django 4.2 every file storage the project uses is declared in one setting, `STORAGES`. It is a dictionary whose keys are **aliases** and whose values are dictionaries with: - `BACKEND`: the dotted path of a storage class. - `OPTIONS` (optional): a dictionary passed to that class's constructor as `**kwargs`. Django's built-in default is: ```python STORAGES = { 'default': {'BACKEND': 'django.core.files.storage.FileSystemStorage'}, 'staticfiles': { 'BACKEND': 'django.contrib.staticfiles.storage.StaticFilesStorage', }, } ``` Two aliases have special meaning: | Alias | Used by | Default backend | |---|---|---| | `default` | `FileField` uploads, `default_storage` | `FileSystemStorage` | | `staticfiles` | `collectstatic`, `{% static %}`, `staticfiles_storage` | `StaticFilesStorage` | Any other alias you add is available through `django.core.files.storage.storages['<alias>']`. ## Switching to hashed static files To enable content-hashed names you change only the `staticfiles` backend: ```python STORAGES = { 'default': {'BACKEND': 'django.core.files.storage.FileSystemStorage'}, 'staticfiles': { 'BACKEND': 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage', }, } ``` `StaticFilesStorage` and `ManifestStaticFilesStorage` both default their location to `STATIC_ROOT` and their base URL to `STATIC_URL`, so no `OPTIONS` are needed for the common case. ## The trap: your value replaces the default The settings reference says it plainly: defining `STORAGES` overrides the default and is **not merged** with it. Two failure modes follow: 1. **Only `staticfiles` defined.** The `default` alias no longer exists. Nothing complains at startup; the first time code touches `default_storage` (for example a model save with a `FileField`) Django raises `InvalidStorageError: Could not find config for 'default' in settings.STORAGES.` 2. **Only `default` defined.** The `staticfiles` alias is missing, and the system check framework reports `staticfiles.E005` ("The STORAGES setting must define a 'staticfiles' storage.") as soon as `manage.py` runs. When you derive test or environment settings from a base module, spreading the base value (`{**STORAGES, 'staticfiles': {...}}`) avoids losing the other alias. ## What OPTIONS can and cannot do `OPTIONS` become constructor keyword arguments. `FileSystemStorage` accepts `location`, `base_url`, `file_permissions_mode`, `directory_permissions_mode` and `allow_overwrite`, and the manifest mixin additionally accepts `manifest_storage`. Behaviour switches such as `manifest_strict`, `max_post_process_passes` and `support_js_module_import_aggregation` are **class attributes**, not constructor arguments. Putting them in `OPTIONS` raises `TypeError` for an unexpected keyword argument when the storage is first created. The supported way is a small subclass referenced by `BACKEND`. ## How the alias is resolved at runtime Nothing reads `STORAGES` at import time. Both special aliases are reached through lazy objects: - `django.core.files.storage.default_storage` resolves `storages['default']` the first time it is used. - `django.contrib.staticfiles.storage.staticfiles_storage` resolves `storages['staticfiles']` the first time it is used, for example by `collectstatic` or the first `{% static %}` render. - `storages` itself builds each backend once per process and caches the instance, so a storage's constructor (and, for the manifest backend, the reading of `staticfiles.json`) runs once per alias per process. This is why configuration mistakes in `STORAGES` often surface late: a wrong dotted path, an unknown `OPTIONS` key or a missing alias fails on first use rather than at startup, unless a system check covers it. Running `collectstatic` in the build exercises the `staticfiles` alias early, which is one more reason to make it part of every release. ## What happened to STATICFILES_STORAGE - Before 4.2, `STATICFILES_STORAGE` held the static files backend and `DEFAULT_FILE_STORAGE` the upload backend. - Django 4.2 added `STORAGES` and deprecated both old settings. - Django 5.1 removed them, along with `get_storage_class()`. On Django 6.1 a leftover `STATICFILES_STORAGE` line is simply an unused setting: it does nothing, so a project upgraded without migrating it quietly falls back to the plain `StaticFilesStorage` and loses cache busting. Search old settings modules for both names when upgrading.

  • A project upgraded from Django 4.1 to 6.1 still has STATICFILES_STORAGE set to the manifest backend; what does it serve now?
    The old setting was removed in 5.1, so Django 6.1 ignores it. With no `STORAGES` override the `staticfiles` alias uses the default `StaticFilesStorage`: files are collected under their original names, no manifest is written and cache busting silently stops. Move the value into `STORAGES['staticfiles']['BACKEND']`.
  • How do you reach the configured static storage from Python code rather than a template?
    Import `staticfiles_storage` from `django.contrib.staticfiles.storage`, a lazy object resolving to `storages['staticfiles']`, and call its `url()` method. It returns the same URL the `{% static %}` tag renders, hashed or not depending on `DEBUG` and the configured backend.

saying these in an interview costs you the question

  • Defining STORAGES with only a staticfiles entry keeps the default upload storage.
  • STATICFILES_STORAGE still works in Django 6.1 with a deprecation warning.
  • manifest_strict can be switched off through OPTIONS in STORAGES.
  • ManifestStaticFilesStorage is enabled by adding it to INSTALLED_APPS.