EDIT/Workaround:
I got this working. I think there is an unfortunate interaction of FORCE_SCRIPT_NAME
, the requirement for STATIC_URL
to end in /
, and the behavior of django.conf.urls.static
. I'll mark this answered when I'm able to put together a step-by-step explanation.
Meanwhile, here's the recipe that works for me:
urls.py
from django.conf.urls.static import static
urlpatterns += static("static", document_root=settings.STATIC_ROOT)
settings.py
FORCE_SCRIPT_NAME = "/the-prefix-i-need/"
STATIC_ROOT = "/static/"
STATIC_URL = "static/"
STATIC_URL
has to end with "/" (or runserver
fails). But if static
's first argument ends with /
it pulls in the FORCE_SCRIPT_NAME
into the URL pattern it is looking for, and doesn't match "/static"
In development (DEBUG=True) mode, running in docker on a host where the site is served with a prepended path corresponding to a branch, I am unable to get static files working.
Using python 4.0.6
In settings.py
I have these settings:
DEBUG = True
BASE_DIR = Path(__file__).resolve().parent.parent # default generated
FORCE_SCRIPT_NAME = "https://pmdocker01d.pm.local:8443/bi-web-utils/ta0624/"
INSTALLED_APPS = [
...
'django.contrib.staticfiles',
STATIC_URL = 'static/'
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
In my html file:
{% load static %}
<html>
<head>
...
<link rel="stylesheet" href="{% static 'tableau_explorer/style.css' %}">
And my css is in:
django_root/tableau_explorer/static/tableau_explorer
On my development machine, both running manage.py from the sheel, and in a dockerfile, it works. In that setting, I don't have FORCE_SCRIPT_NAME.
When it is on the other docker host, the generated HTML
<link rel="stylesheet" href="/static/tableau_explorer/style.css">
And I get a 404 error.
If I change:
STATIC_URL = 'https://pmdocker01d.pm.local:8443/bi-web-utils/ta0624/static/'
Then it instead of a plain 404 I get message that it's getting HTML instead of css, because the server is returning this
Request Method: GET
Request URL: http://https://pmdocker01d.pm.local:8443/bi-web-utils/ta0624/static/tableau_explorer/style.css
Using the URLconf defined in bi_web.urls, Django tried these URL patterns, in this order:
admin/
....
The current path, static/tableau_explorer/style.css, didn’t match any of these.
For the other docker host I tried adding this to the main project urls.py (not tableau/explorer/urls.py) I tried adding this and and couldn't see any difference:
from django.conf import settings
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns = [ . . . . ]
if settings.DEBUG:
urlpatterns += staticfiles_urlpatterns()
If I browse to https://pmdocker01d.pm.local:8443/bi-web-utils/ta0624/static/
I get the error message "Directory indexes are not allowed here.", whereas other urls like making it end "staticx/" it just says page not found. So I think static is doing something, but I can't tell that anything at all is being gathered there and don't know how to check.
If I make a shell connection into the running docker host, it seems like static is finding what I'd expect:
$ python manage.py findstatic tableau_explorer/style.css
Found 'tableau_explorer/style.css' here:
/code/tableau_explorer/static/tableau_explorer/style.css
Anyone know right off what's going on and can tell me "type this and it'll work?"
If not...
My question now is - what is the staticfiles supposed to be doing with files in development mode, and how does it serve them?
is it supposed to intercept any request that begins with "static/"
when the app starts running, does staticfiles gather the .css files from different applications "static" folders, and put copies into an on-disk repository I can verify, or put verbose logging on? -- Should I be able to see the files in a particular directory on the running server?
is the BASE_DIR setting relevant to staticfiles? I am using what was generated by
manage.py createproject
in staticfiles nowadays, is it supposed to take care of appending "static" into the urls? I thought I shouldn't need to modify urls.py?
-- Edit:
Since posting I added STATIC_ROOT=/static
in the settings.py file, and in Dockerfile I added collectstatic. When I shell into the running docker image on the host I see
$ ls -l /static/tableau_explorer/style.css
The files are present good, and are other-accessible all the way down.
The rendered HTML file has
<link rel="stylesheet" href="https://pmdocker01d.pm.local:8443/bi-web-utils/ta0624/static/tableau_explorer/style.css">
and if I browse directly to that link, Django is complaining it doesn't match any path... I feel like I have to do something in urls.py to give the request to staticfiles to handle?
The response when I browse is the familiar:
<html lang="en"><head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Page not found at /static/tableau_explorer/style.css</title>
</head>
<body>
<div id="summary">
<h1>Page not found <span>(404)</span></h1>
<table class="meta">
<tbody><tr>
<th>Request Method:</th>
<td>GET</td>
</tr>
<tr>
<th>Request URL:</th>
<td>http://https://pmdocker01d.pm.local:8443/bi-web-utils/ta0624/static/tableau_explorer/style.css</td>
</tr>
</tbody></table>
</div>
<div id="info">
<p>
Using the URLconf defined in <code>bi_web.urls</code>,
Django tried these URL patterns, in this order:
</p>
<ol>
. . . . Nothing about "/static" . . .
</ol>
<p>
The current path, <code>static/tableau_explorer/style.css</code>,
didn’t match any of these.
</p>
....