My local testing server for Django v1.8.2 on Windows 8.1 is only serving certain static files. Others are giving a 404 error.
#urls.py - excerpt
urlpatterns = [
url(r'^$', views.index)
] + staticfiles_urlpatterns()
#settings.py - excerpt
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'main',
'users'
)
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
As far as I can tell the development server is configured to serve static files. When running runserver I get no warnings, and my code displays no syntax errors (import statements do exist and so forth). I did for testing purposes run collectstatic before starting the server just to be sure at least once.
My view template is:
{% load staticfiles %}
<img src="{% static 'main/img/ComingSoon.jpg' %}" alt="Coming Soon">
The link generated is /static/main/img/ComingSoon.jpg which looks correct, the file does exist in that location. What perplexes me is that this directory produces a 404 error, but other static files are served. The directory hierarchy is:
static/
admin/
css/
..
js/
..
img/
..
main/
img/
ComingSoon.jpg
The URL localhost:8000/static/admin/img/ gives an expected message about indexes being not allowed. However, localhost:8000/static/main/img/ reports \main\img\ cannot be found. Both are 404 statuses. Images within static/admin/img/ do display correctly with the same links as what is giving an error. The Administration site for Django does display correctly.
Why would one directory within static/ not be indexed or accessible?
According to the Django documentation regarding static/:
This should be an initially empty destination directory for collecting
your static files from their permanent locations into one directory
for ease of deployment; it is not a place to store your static files
permanently. You should do that in directories that will be found by
staticfiles’s finders, which by default, are 'static/' app
sub-directories and any directories you include in STATICFILES_DIRS).
I moved the files to another directory such as:
myApp/
main/
static/
main/
img/
..
static/
..
After running collectstatic I noticed the script created the subdirectories in myApp/static/ as expected and it must have generated the URLs needed because it now properly serves the files.
Related
I have a Django (3.1) app that I've set up to serve static files, that is, myapp/settings.py has
DEBUG = True
.
.
.
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'myapp',
.
.
.
]
.
.
.
STATIC_URL = '/static/'
STATIC_ROOT = 'static/'
But instead of serving files from the static directory of myapp, it's serving static files from /Library/Python/3.7/site-packages/django/contrib/admin/static/. I have tested this by adding files to both directories,
~/Projects/myapp/static/file-from-project.js
/Library/Python/3.7/site-packages/django/contrib/admin/static/file-from-library.js
and then
python3 manage.py runserver
with a template including the lines
<script src="{% static 'file-from-project.js' %}"></script>
<script src="{% static 'file-from-library.js' %}"></script>
and file-from-library.js loads fine but I get a 404 for file-from-project.js. What am I doing wrong here?
Directory structure with the referenced files:
myapp
/myapp
settings.py
.
.
.
/static
file-from-project.js
.
.
.
/templates
.
.
.
manage.py
.
.
.
OK, I see the problem I think.
STATIC_ROOT is an absolute path, not a relative one. if you set it to eg. BASE_DIR / "static" you might get what you want.
I usually set BASE_DIR at the top of my settings.py as it gets used for a few things:
BASE_DIR = Path(__file__).resolve(strict=True).parent.parent
The other thing is that you have DEBUG=True which means it's going to be looking at your STATIC_URL under your app dirs. If you move the file to:
~/Projects/myapp/static/app_folder/file-from-project.js
It should work :)
Edit: I noticed myapp is an app, and not the project name, which makes me wonder what the project is called.
Your static files for development for this structure should probably be in:
~/Projects/myapp/static/myapp/<static file>
When you deploy, obviously DEBUG should be False, but here you should run collectstatic in order to gather all the static files in one place for deployment.
My app consists of django and react, which at the end is bundled to static (.js) file.
My goal is to setup a nginx for it, but for now I just want to run in uwsgi to see if it works.
Aaaaand it does not work at all. I belive there is a issue with loading this bundle file which webpack is compiling.
Connection to uwsgi works, server is up and running, but when connecting to 127.0.0.1:8080 I get (in Mozilla):
The resource from “http://127.0.0.1:8080/static/frontend/main.js”
was blocked due to MIME type (“text/html”) mismatch
(X-Content-Type-Options: nosniff).
# and another
GET http://127.0.0.1:8080/static/frontend/main.js
HTTP/1.1 404 Not Found
Content-Type: text/html
X-Frame-Options: DENY
Content-Length: 3277
X-Content-Type-Options: nosniff
Referrer-Policy: same-origin
Vary: Origin
Similar topic I found: Difference between static STATIC_URL and STATIC_ROOT on Django
and this: Django + React The resource was blocked due to MIME type (“text/html”) mismatch (X-Content-Type-Options: nosniff)
But messing with python manage.py collectstatic resolved nothing.
I have this lines of code to manage static files:
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join('/app/label_it/front/static/frontend/')
And this is how I start my uwsgi connection:
python manage.py collectstatic --no-input
uwsgi --http 0.0.0.0:8080 --master --enable-threads --module label_it.wsgi
Beside collectstatic I've tried messing with <script src"static_file_path"></script> this static path with:
<script src="../../static/frontend/main.js"></script>
# and
<script src="{% static "frontend/main.js" %}"></script>
Which result in nothing.
Any clues appreciated !
EDIT:
My file structure:
Ok I just did some testing with my own server and django project to confirm my suspicion and I've come to the following conclusion: This error will happen if the path to the static file doesn't exist. Meaning that uwsgi cannot find this main.js file with the settings you have.
My suggestion would be to do the following to ensure your static files are being served correctly in a way that django knows where to look.
By default django searches inside each installed app for a static folder to find static assets. Because your project is not setup that way you have to specify additional directories where static files live.
This is what STATICFILES_DIRS is for.
In your settings.py put the following
STATICFILES_DIRS = [
BASE_DIR / 'label_it/front/static'
]
This will make all files inside label_it/front/static discoverable to django.
Now this means that
<script src="{% static "frontend/main.js" %}"></script>
will (hopefully) work.
additionally, remember to include your static urls in your urls.py file if you haven't already.
urls.py
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns = [
...
]
# static content urls
urlpatterns += staticfiles_urlpatterns()
Sidenote: STATIC_ROOT is intended to be the location where all static files will be collected to when you run python manage.py collectstatic.
As such it should be an empty directory, preferably in the root of your django project.
STATIC_ROOT = os.path.join(BASE_DIR, 'static_collected')
The name of the folder doesn't really matter and I've used static_collected as an example.
If you run the command hopefully you'll see all the files in label_it/front/static/ copied there.
I have a frontend react app, after using npm run build it creates build folder with:
build
favicon.ico
index.html
service-woker.js
static
After using django's python manage.py collectstatic I noticed what django has done was that it pulls out only the static folder, favicon.ico is not pulled out. So, my website icon doesn't work.
In my index.html, <link rel="apple-touch-icon" href="%PUBLIC_URL%/favicon.ico" />
In my settings.py
STATICFILES_DIRS = [
os.path.join(BASE_DIR, '../frontend/build/static')
]
STATIC_ROOT = '/var/www/web/home/static/'
STATIC_URL = 'home/static/'
In chrome inspect in the headers element:
<link rel="icon" href="./home/favicon.ico">
How do I get it to display my web icon. Thankyou!
It is clear in documentation that Django collectstatic looks only for files in folders that are set in
STATICFILES_DIRS = [
os.path.join(BASE_DIR, '../frontend/build/static')
]
This will copy all files from your static folders into the STATIC_ROOT
directory.
your favicon is not in any of listed staticfiles directiories
Second thing is that Django static files are only accessible from full STATIC_URL path ( you cannot use just .home/ path)
Fix would be one of following
to simply add icon inside static folder
use ngnix to serve static files and add proper blocks ( prefered )
change STATIC_ROOT='/var/www/web/home/' and STATIC_URL = 'home/' ( note this way index.html and rest of files in home would be accessible as staticfiles)
I'm trying to migrate my project from using {% compress %} to grunt for the whole front-end workflow. I got my grunt setup correctly and I can generate my main.min.css and main.min.js. With collectstatic I see them copied to the right folder, but when I deploy to staging all I get is a big fat 500 error.
INSTALLED_APPS = (
'django.contrib.contenttypes',
'django.contrib.messages',
'django.contrib.staticfiles',
'captcha',
'core',
)
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'
STATICFILES_FINDERS = (
"django.contrib.staticfiles.finders.FileSystemFinder",
"django.contrib.staticfiles.finders.AppDirectoriesFinder",
"compressor.finders.CompressorFinder",
)
and in the template:
<link rel="stylesheet" href="{% static "core/dist/css/main.min.css" %}" />
It works locally if I set DEBUG=False in settings.py (without loading the static files obviously). Any idea?
For everyone ending up here in the future: check your .gitignore file and be sure to only reference existing files in the template!
In my case I had dist/ in my .gitignore and I was storing my static files in core/dist/ so they got gitignored and ended up not being on the server.
I have problems with deploying files in my development environment.
See my configuration below.
python manage.py collectstatic collects all files from '/Users/vikingosegundo/Projects/website/media/' as expected and stores them at /Users/vikingosegundo/Projects/website/mydjangoproject/static/.
But although the links to the css files are correct when using <link href="{% static "css/style.css"%}" rel="stylesheet" type="text/css"> (rendered as <link href="/staticmedia/css/style.css" rel="stylesheet" type="text/css">), the originals files at /Users/vikingosegundo/Projects/website/media/ will be deployed, not from the STATIC_ROOT /Users/vikingosegundo/Projects/website/mydjangoproject/static/.
Even if I delete the files that are in /Users/vikingosegundo/Projects/website/media/.
Where is my misconfiguration?
settings.py
MEDIA_ROOT = '/Users/vikingosegundo/Projects/website/mydjangoproject/media/'
MEDIA_URL = '/sitemedia/'
STATIC_ROOT = '/Users/vikingosegundo/Projects/website/mydjangoproject/static/'
STATIC_URL = '/staticmedia/'
STATICFILES_DIRS = [
'/Users/vikingosegundo/Projects/website/media/',
]
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.auth.context_processors.auth',
'django.core.context_processors.debug',
'django.core.context_processors.i18n',
'django.core.context_processors.media',
'django.core.context_processors.static',
)
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
#....
)
I think, this is because the serving of static files using the django build-in views and helpers is intended for development and debugging purposes only. When DEBUG is True in your project settings, your static files are served from their original location. This helps to avoid being forced to run the collectstatics management command every time you for example change your CSS files.
When you switch your DEBUG setting off, django.conf.urls.static.static and its cousins helpers will stop working, since they are intended for development purposes only. Still, the template tags will work, since they must point to the correct static file urls in either production or development.
Running the collectstatic management command is a convenient helper for copying your static files to their final destination (STATIC_URL), where serving them in a production environment is your own responsibility. This is best done by an (static) web server location (avoiding pumping them through the django/python process), and thus Django's docs explicitly recommend to not use Django for static file serving.
See Managing static files: Serving static files in development for more about serving static files in development.