Django static files do not resolve constant 404 errors - python

I am new to Django current version I'm running is 1.11 with python 3. I have configured the static file stuff as the docs suggest. Inside installed apps I have 'django.contrib.staticfiles'
nonprofit/nonprofit/settings.py
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATIC_URL = '/static/'
STATICFILES_DIR = (
os.path.join(BASE_DIR, "static/"),
)
And django seems to be working as far as putting the right path in the template. Though even if I hardcode the path into the template the browser still gives a 404 not found.
I have a base.html template, with some css.
{% load staticfiles %}
<!--Bootstrap-->
<link rel="stylesheet" href="{% static 'css/bootstrap.css' %}">
<link rel="stylesheet" href="/static/css/bootstrap-theme.css">
My directory structure is --
nonprofit
- goals
- nonprofit
- static
- css
bootstrap.css
bootstrap-theme.css
- templates
base.html
db.sqlite3
manage.py
From the browser it shows both 404 not found errors as well as not being able to go straight to the files-
GET http://127.0.0.1:8000/static/css/bootstrap.css 127.0.0.1/:19
GET http://127.0.0.1:8000/static/css/bootstrap-theme.css 127.0.0.1/:20
I don't think the problem is with django because it shows the right path, but even the hardcoded one cannot be accessed through the browser. I'm running the development server. Whats going on with this stuff? Do I have something wrongly configured or lacking configuration? Any help is appreciated. I have looked at all the suggested posts and have tried various things without any good results.

The setting name is STATICFILES_DIRS. You are missing the S.

Related

Django admin wont load certain static files

I have a strange issue that's occurred on several django projects and I'm trying to figure out a fix for it. For some reason, all the static files for the admin area load properly including the js, css, and images but 2 files for the side nav bar (which are in my static directory along with everything else) wont load. The files are the nav_sidebar.css and nav_sidebar.js.
I've figured out a work around and added these inline in the admins base.html template and deleted the links to these files. This works but it's kind of ridiculous that it manages to load all other static assets fine but not these particular files. I have my static root and directories set up properly, have nginx pointing to the correct static directory, and have done collect static and restarted the server. Everything I could possibly think of but it doesn't work.
Considering this has happened on 3 straight projects, I think this is some kind of bug rather than an error on my end.
So I was able to answer my own question in the end and for anyone else that comes across this problem here are the steps I took.
For the admin static files, before you run collect static are being sourced directly from the wherever your python(versionNumber)/site-packages/django/contrib/admin/static is located. Unless you run collect static, or manually copy and paste them into your static files directory, these admin files wont be there.
Now I'm sure this is basic knowledge for any django user and I even did this and the error still persisted. What I found, is that I set my static urls up like:
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
And for some reason, django was still sourcing the admin files from that same directory the django source is located. So I simply changed the url path and static root to:
STATIC_URL = '/staticfiles/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
And ran manage.py collectstatic again and that fixed my admin area and everything is working properly now.
These two files are introduced in django 3.1 for nav_sidebar feature. In admin/base.html, it says:
{% if not is_popup and is_nav_sidebar_enabled %}
<link rel="stylesheet" type="text/css" href="{% static "admin/css/nav_sidebar.css" %}">
<script src="{% static 'admin/js/nav_sidebar.js' %}" defer></script>
{% endif %}
is_nav_sidebar_enabled by default is enabled. Did you put something in the root urls.py to disable that?
something like:
admin.site.enable_nav_sidebar = False in your root urls.py?
The doc about the new nav_sidebar feature is here

importing image to django page

I am trying to attach an image to my page (per https://docs.djangoproject.com/en/1.10/howto/static-files/#configuring-static-files), but it cannot be displayed: http://prntscr.com/evwern
settings.py
STATIC_URL = '/portfolio/'
urls.py
urlpatterns = [
url(r'^$', index, name='index'),]
index.html
{% load static %}
<img src="{% static '/catalog/static/portfolio/oh_i_ah.jpg' %}" alt="My image" style="width:640px;height:473px;"/>
Path to the image: mysite/portfolio/catalog/static/portfolio/oh_i_ah.jpg
If I try to open the image in the new tab it throws:
Page not found (404)
Request Method: GET
Request URL: http://127.0.0.1:8000/portfolio/catalog/static/portfolio/oh_i_ah.jpg
1) You did not specify your app directory name. Need to know the app/directory name to answer your question properly.
2) You did not use 'static' properly.
3) You did not specify whether you are using default django development server or some production server. I am assuming that it's default django development server with DEBUG=True.
Solution
Let's imagine: You have an app named app0 (let's say you created that with "python manage.py startapp app0") and you have created a directory called "static " inside of that (following default django convention over configuration). Inside of this 'static' directory you have created another directory called 'app0'. So, you are going to put your file inside "/app0/static/app0". So, your file path becomes: "/app0/static/app0/oh_i_ah.jpg"
Now, set STATIC_ROOT properly in the settings.py
In the template file refer the file as {% static "app0/oh_i_ah.jpg" %} (without leading forward slash).
Now, everything will be ok.
Yes, you can put the static files outside of any app directory if you configure STATICFILES_DIRS, STATIC_ROOT in settings.py correctly.
Please properly describe your problem with as much details as possible so that we can help you in the right way.
in settings.py
import os
STATIC_URL = '/portfolio/'
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'), )
STATIC_ROOT = os.path.join(BASE_DIR, 'static_root')
and
python manage.py collectstatic
in index.html
{% load staticfiles %}
<img src="{% static '/portfolio/oh_i_ah.jpg' %}" alt="My image" style="width:640px;height:473px;"/>

STATICFILES_DIR does not work on Apache web-server

I'm testing one and the same application both on the default Django server and on Apache and I see a lot of big differences. I managed to resolve some of them, but at this moment I'm unable to resolve a major difference. So, in project settings.py file I have this code:
MODULES_DIR = BASE_DIR + '/system/modules/'
for item in os.listdir(MODULES_DIR):
stat = os.path.join(MODULES_DIR, item + '/static')
if os.path.isdir(os.path.join(MODULES_DIR, item)):
INSTALLED_APPS += ('system.modules.%s' % item, )
STATICFILES_DIR += (stat, )
APPS_DIR = true
This code is supposed to populate INSTALLED_APPS dynamically, based on the contents of BASE_DIR + '/system/modules/' folder. In other words, if there is a folder inside /modules, this folder becomes an application. Likewise, I build dynamically STATICFILES_DIR - in this case it is supposed, that every single folder/application (which is inside /modules folder) has a /static folder with static contents - js, css etc. For example, it may be such a construct:
\modules
\DefaultModule
__init__.py
urls.py
views.py
\static
test.js
\templates
DefaultModule.html
And DefaultModule.html in this example loads static files like this:
<html>
<head>
{% load static from staticfiles %}
<script type="text/javascript" src="{% static "test.js" %}"></script>
It is rather interesting, but on default Django server this logic works perfectly, so that when I go in my browser to localhost/DefaultModule/, I see a template DefaultModule.html loaded and I see test.js file loaded from http://localhost/DefaultModule/static/. However, on Apache the template is rendered too, but the test.js file is loaded from http://localhost/static/ what eventually results in a 404 NOT FOUND error. So, for some reason Apache server does not take into account STATICFILES_DIR. And yes I checked its (I mean STATICFILES_DIR) contents and it is the same. In both cases STATICFILES_DIR contains modules/DefaultModule/static/, but on Apache it is ignored for some reason. Hope someone can help. Thanks!
I think you should read the Django docs on static files. Looks like you're falling into the simple and old Django Static File Hosting an Apache
Check it out and let us know.

Is there a way to load file that is under templates folder on Django HTML?

I could load css file on Django html like this
{% load staticfiles %}
<link rel="stylesheet" href="{% static "css/style.css" %}">
I wonder why I can't load css file that is under templates folder.
<link rel="stylesheet" href="css/style.css">
Is there a way to load file that is under templates folder on Django HTML?
Why does Django wants me to put {% static "css/style.css" %} this format on all static files? Is it because much faster to load?
What If I load file that is under templates folder? Is it slow to load?
Templates and static assets are two differents types of assets that need to be managed differently for security purposes.
All js, css and images files need to be provided to clients in order for your website to be working. They are handled from the client side so they need to be available. So static asset folder is made to be available, if you check view source and follow the link of these assets you'll see they can be opened directly in your broswer.
Templates however are used by django itself to generate the output that is set via your views. When a user opens a page, he doesn't access the template itself but the rendering made by django. So the template folder isn't accessible to end user by design, including the files that are in it. So the only things a user can access from a django application are the responses given by the views, that are based on urls patterns and the templates, and assets that are in static folder. So you can't, and shouldn't, link to static assets from anywhere else but your static folder.
As I can see it, you have missed the concept of the templates and the static files in Django.
First of all, there are two independent mechanisms: loading a template file (your future HTML file) and loading your static files (css, js, images).
When loading a template Django uses TEMPLATE_LOADERS (docs), which are basically defined in your settings.py as:
TEMPLATE_LOADERS = (
# Loads templates from DIRS setting:
'django.template.loaders.filesystem.Loader',
# Loads templates from your installed apps:
'django.template.loaders.app_directories.Loader',
)
You can define a location of yout templates by setting DIRS (if you are using Django >= 1.8) or TEMPLATE_DIR (if Django < 1.8). There are several more steps in rendering your template such as: template context processors and so on, but it is all listed in the documentation.
Now about static files.
Static files are served by django.contrib.staticfiles app (docs) when DEBUG = True. In production it is done by Nginx, Apache or other Http-Servers.
When loading a static file Django uses STATICFILES_FINDERS. They are usially defined as:
STATICFILES_FINDERS = (
# Loads static files from STATICFILES_DIRS:
"django.contrib.staticfiles.finders.FileSystemFinder",
# Load static files from installed apps:
"django.contrib.staticfiles.finders.AppDirectoriesFinder"
)
There are two main settings to care about: STATIC_URL and STATICFILES_DIRS.
STATIC_URL is basically just a prefix, which is used to get your static files. It is almost always just '/static/'. And in STATICFILES_DIRS there are paths to your static files folders. It is sometimes extended to include node_modules, bower_components or things like that.
When dealing with static files in templates you need to append your STATIC_URL to your file's URL. The easiest way to do that is {% static %} tag.
A lot of confusion comes with STATIC_ROOT. It is just a path, where all your static files will be collected in production after running collectstatic management command.

Django CSS. I get the HTML page with no CSS

I have had this problem for a while now, I have been trying to move my CSS file all over the place and changing the settings, and even messing with the media url stuff, which I don't believe I should be now that I have read other questions.
My CSS file is in the /home/justin/test/static/ directory. My templates are in the /test/templates directory.
My settings are:
STATIC_ROOT = '/home/justin/test/static/'
STATIC_URL = '/static/'
STATICFILES_DIRS = (
'/home/justin/test/static/',
)
My urls are:
urlpatterns = patterns('',
url(r'^$', 'views.home'),
# Static Files
url(r'^static/(?P<path>.*)$','django.views.static.serve', {'document_root':settings.MEDIA_ROOT}),
)
I have all three in my main template.
<link rel="stylesheet" href="/static/style.css" />
<link rel="stylesheet" href="{{ STATIC_URL }}style.css" />
<link rel="stylesheet" href="{{ STATIC_URL }}/style.css" />
They come out:
<link href="/static/style.css" rel="stylesheet"></link>
<link href="style.css" rel="stylesheet"></link>
<link href="/style.css" rel="stylesheet"></link>
The first comes out to the correct file, but it doesn't work.
Any help is really appreciated. Thank you.
My views.py:
from django.shortcuts import render_to_response
def home(request):
return render_to_response('index.html',{})
My error from the terminal is:
[16/Aug/2013 21:00:21] "GET /static/style.css HTTP/1.1" 500 1729
You need to pass request in RequestContext of your views
def home(request):
return render_to_response('index.html', locals(), context_instance = RequestContext(request))
Only then your session data will be passed to the template and {{ STATIC_URL }} will work.
Here are some tips to help you solve this problem.
First, anything to do with MEDIA_ is referring to files that are uploaded to the system by users; and STATIC_ refers to files that are part of your application.
STATIC_ROOT should point to the file system path where the collectstatic command will dump all the static files from all your applications. When you are deploying the application into a production environment, you run collectstatic (which will overwrite everything in the directory pointed to by STATIC_ROOT) and then copy the contents of this directory to a location that is mapped to the url that STATIC_URL points to.
In summary:
If your application needs any static files (images, javascript, css, etc.) create a directory called static in your application's directory (the same location where you have models.py) and add the files there.
STATIC_ROOT should point to a directory where all the images, css, javascript, etc. will be dumped by the collectstatic command. This is only used when you want to move your application to a production server. The collectstatic command will grab all the files in all the static directories in your applications that are listed in INSTALLED_APPS (including the ones from the django.contrib like the admin interface) and dump them in this directory. You would then take this directory and copy or move it to your web server.
STATICFILES_DIRS is a directory where any static files that are not part of any specific application should be stored. If this location is set, then django will also look here for static files.
STATIC_URL = the URL path that is configured in your web server to point to the location where all the files in STATIC_ROOT are located.
The {% static %} tag will always point to the STATIC_URL variable. In order to use this tag you must have {% load staticfiles %} at the top of any template that is using the tag; even if the template is inheriting from one that already as the load line in it.
You don't need anything fancy in your urls.py unless you are using django to serve your static files (which you should not do). Use the web server to handle static files. If you are running with DEBUG = True and using runserver, then django will take care of handling static files for you automatically as a courtesy during development.
For any user uploaded files which are controlled by the various MEDIA_* settings you need to handle these manually during development; and for this you can use the following snippet in your urs.py. Again, keep in mind this is only for development - do not use this in production:
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = patterns('',
# ... the rest of your URLconf goes here ...
)
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL,
document_root=settings.MEDIA_ROOT)
Please read the static files section in the manual; from where I have summarized the above points.
Finally, you should use the render shortcut when using methods in your views. This makes sure that the proper request context is always sent.
you must use this tag ({% load static from staticfiles %}) in your template :
{% load static from staticfiles %}
<link rel="stylesheet" type="text/css" href="{% static 'style.css' %}" />
In your urls, you should serve from the STATIC_ROOT not the MEDIA_ROOT setting
url(r'^static/(?P<path>.*)$','django.views.static.serve', {'document_root':settings.STATIC_ROOT})
Also, you need to pass RequestContext on your views, like stated in other answers.
In development mode (which means DEBUG=True in settings.py), to serve static files
Simply put the following lines in urls.py
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
# ... the rest of your URLconf here ...
urlpatterns += staticfiles_urlpatterns()
In production mode, you should use nginx/apache in front of django to serve static files.
Refs: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/
There's a line in your question:
url(r'^static/(?P<path>.*)$','django.views.static.serve', {'document_root':settings.MEDIA_ROOT}),
Normally, settings.MEDIA_ROOT is for user uploaded files, which is a different folder from settings.STATIC_ROOT.

Categories