Reputation: 15309
In development mode, my django app is serving static files from *one of the STATICFILES_DIRS, but not the other.
Here is my code in a settings.py file:
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'bower_components'), # OK
os.path.join(BASE_DIR, 'practice_custom'), # Not OK
]
STATICFILES_FINDERS = [
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
]
Files in bower_components are found, but files in practice_custom are not. Both directories are in the same place (top level). If I rename the bower_components directory to bower_componentszzzzzz then the files are not found, which means they were being found via the staticfiles app.
FileSystemFinder also seems to be working, in fact I put print statements in the code in the find() method(---looking for:), and it shows the paths being provided, as you can see they are formatted the same, but one results in a 404.
---looking for: practice_custom/xyz/style.css
[09/Mar/2017 21:55:11] "GET /static/practice_custom/xyz/style.css HTTP/1.1" 404 1732
---looking for: bower_components/c3/c3.min.css
[09/Mar/2017 21:55:11] "GET /static/bower_components/c3/c3.min.css HTTP/1.1" 200 2043
Any ideas?
EDIT:
Upon inspecting FileSystemFinder.find_location() I saw it was searching for bower_components/bower_components and then had a peak at the bower_components directory at top level and found that it did indeed have a subdirectory called bower_components, and that is the only reason that was working!
Although when I run collectstatic
I get static/bower_components/bootstrap etc... as I'd expect to see.
/manage.py
/bower_components/bower_components/bootstrap
/static/bower_components/bootstrap
/...
So I suppose, the question is WHY does it do this?!
Upvotes: 1
Views: 110
Reputation: 1092
It's because of Django behavior that uses a namespace inside every static directory. It expects you to have an unique subdirectory inside every static folder to avoid name conflicts.
Static file namespacing
Now we might be able to get away with putting our static files directly in my_app/static/ (rather than creating another my_app subdirectory), but it would actually be a bad idea. Django will use the first static file it finds whose name matches, and if you had a static file with the same name in a different application, Django would be unable to distinguish between them. We need to be able to point Django at the right one, and the easiest way to ensure this is by namespacing them. That is, by putting those static files inside another directory named for the application itself.
https://docs.djangoproject.com/en/howto/static-files/
So if you have:
├── django_app
│ ├── practice_custom
│ │ ├── example_root.js
│ │ ├── xyz
│ │ │ ├── style.css
│ ├── bower_components
│ │ ├── bower_components
│ │ │ ├── bootstrap
Then your static files will be available at:
/static/bower_components/bootstrap
/static/xyz/style.css
/static/example_root.js
Upvotes: 1