WHITENOISE_STATIC_PREFIX still required if django app deployed on subpath
See original GitHub issueThe docs for WHITENOISE_STATIC_PREFIX currently say
Default: Path component of settings.STATIC_URL (with settings.FORCE_SCRIPT_NAME removed if set) … If your application is not running at the root of the domain and FORCE_SCRIPT_NAME is set then this value will be removed from the STATIC_URL path first to give the correct prefix.
I understand this to mean if in my settings.py I have
FORCE_SCRIPT_NAME = "/dev"
STATIC_URL = "{}/static/".format(FORCE_SCRIPT_NAME)
WHITENOISE_STATIC_PREFIX
will automatically be /static/
However, this is not the case and i still need to explicitly set in my settings.py
WHITENOISE_STATIC_PREFIX = "/static/"
otherwise static files will not work.
Is this a bug, or am I misunderstanding something in the docs? I did see https://github.com/evansd/whitenoise/issues/164 which seems similar but different enough (no mention of FORCE_SCRIPT_NAME
) where it explicitly mentions needing to do this, but that issue is from 2017 and seems to contradict the above documentation.
am using
- whitenoise 5.2.0
- zappa 0.52.0
- django 3.1.4
Issue Analytics
- State:
- Created 3 years ago
- Comments:6 (1 by maintainers)
I believe this is still an issue, I’ve been experiencing incorrect pathing from static assets with whitenoise which I spent a bit of time debugging in https://github.com/TandoorRecipes/recipes/issues/1878 and https://code.djangoproject.com/ticket/34028.
The root cause seems to be that recent Django versions cache the prefix and setting values based on their first access. Normally first access is a HTTP request so SCRIPT_NAME would be set on it and all is well… However, whitenoise attempts to access the configured STATIC_URL during middleware initialization, as you can see here:
Since this is during initialization and outside a HTTP request context, SCRIPT_NAME is absent and therefore the Django prefix gets incorrectly returned as ‘/’ (i.e. STATIC_URL gets set to ‘/static/’ and then remains that way). This causes all the asset URIs to be wrong when a real request comes in with SCRIPT_NAME header set.
In theory setting FORCE_SCRIPT_NAME should address this by short-circuiting SCRIPT_NAME and ensuring the Django prefix is set correct on whitenoise middleware initialization, but in my testing I didn’t see that behavior. The prefix only gets set on the first HTTP request, so until then even with FORCE_SCRIPT_NAME set the prefix is still ‘/’ according to Django - and that’s what whitenoise sees. Note sure if thats a Django issue or if whitenoise needs to add an explicit check for FORCE_SCRIPT_NAME.
I had a similar issue which I solved by setting
WHITENOISE_STATIC_PREFIX = "/static/"
although I’m not sure why this worked.