Django staticfiles app help - python

I've having a little issue with Django's staticfiles app.
I have added
'django.contrib.staticfiles',
to my INSTALLED_APPS and have added
STATIC_URL = '/static/'
STATIC_ROOT = '/Users/kevdotbadger/django/mylook/static/'
to my settings.py file.
All my static files are located within the STATIC_ROOT folder on my Mac.
Now, within my template I use
{{ STATIC_URL }}
which correctly renders to /static/.
However
{{ STATIC_URL }}css/style.css
result in a 404 error. I'm using the 'runserver' command as the server.
Is there something I'm missing?

I implore you to read the howto docs here: http://docs.djangoproject.com/en/dev/howto/static-files/
In short: STATIC_ROOT is only used if you call the collectstatic manangement command. It's not needed to add the directory to the STATICFILES_DIRS setting to serve your static files!
During development (when the automatic serving view is used) staticfiles will automatically look for static files in various locations (because you call its "serve" view with a path to a static file). For this search it'll use the so called "finders" (as defined in the STATICFILES_FINDERS setting).
One of the default finders is the AppDirectoriesFinder, which will look in the "/static/" directory of each of the apps of yours INSTALLED_APPS setting.
Another default finder is the FileSystemFinder, which will look in directories you specify in the STATICFILES_DIRS setting.
BTW, both these search patterns are similar to how template loading works.
The same technique will be used when running the collectstatic command, except that it now will collect the files from the various locations (using the same finders as above), putting the found files into STATIC_ROOT, ready for deployment.

If you want just a solution - scroll down to the "Solution".
Overview
I was discovering the same problem yesterday. Here is what I found:
All you need is appropriate static finder, that will find your STATIC_ROOT and all its contents, but there is no such finder. Here are default finders:
django.contrib.staticfiles.finders.AppDirectoriesFinder - search installed django applications dirs for 'static' folder, but most of them use obsolete 'media' folders for now.
django.contrib.staticfiles.finders.FileSystemFinder - use all dirs mentioned in the STATICFILES_DIRS, but you can't add STATIC_ROOT into it.
django.contrib.staticfiles.finders.DefaultStorageFinder - search static in your DEFAULT_FILE_STORAGE which is django.core.files.storage.FileSystemStorage by default and it points to your MEDIA_ROOT
Solution
That's all, no additional choices. There are no choices to use STATIC_ROOT for now (in Django 1.3).
So I've just wrote my own custom finder for these needs:
My custom static finder file: finders.py:
from django.core.files.storage import FileSystemStorage
from django.contrib.staticfiles.finders import BaseStorageFinder
from django.conf import settings
class StaticFinder(BaseStorageFinder):
storage = FileSystemStorage(settings.STATIC_ROOT, settings.STATIC_URL)
settings.py:
STATICFILES_FINDERS = (
'finders.StaticFinder',
)
If you want to use it with another finders - I suggest to put them after it inside STATICFILES_FINDERS
And remember: this solution should be used only in development needs and never on production!

I found a quick and easy workaround to serve project global static files during development:
Start a new app that contains your projects static files (e.g. "manage.py startapp static_content")
Create a folder named 'static' in that app and put your static files there.
Add your new app to the list of installed apps

First of all, make sure that you have static serve enabled in your urls.py FOR DEVELOPMENT ONLY.
Also, you may have an extra slash in there. If your STATIC_URL == '/static/', then
{{ STATIC_URL }}/css/style.css should be {{ STATIC_URL }}css/style.css.

STATIC_ROOT = '/home/ws/be/bla/'
STATICFILES_DIRS = ('/home/ws/be/static/',)
STATIC_URL = '/static/'
This works for me. STATIC_ROOT must differ from STATICFILES_DIRS (Django version 1.4 pre-alpha SVN-16436)

Related

Django can't find my static files after changing to production settings and back

I've been trying to deploy my site this weekend and have thus been meddling with the settings. One of the unpleasant surprises while doing this has been that my static files have seemingly stopped working on my site. My CSS files and javascript files don't work anymore, as if they aren't found by the site. The only thing I can remember doing with regards to static files was inserting this into settings.py:
# The absolute path to the directory where collectstatic will collect static files for deployment.
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
# The URL to use when referring to static files (where they will be served from)
STATIC_URL = '/static/'
I removed these settings and replaced them with the original
STATIC_URL = '/static/'
but alas, the problem remains. Why isn't Django finding my static files anymore?
PS: As I'm a noob, I don't know exactly what is relevant from my project for you guys to see, but do let me know and I shall provide additional info.
Okay, update your settings.py as below:
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static_my_proj"),
]
STATIC_ROOT = os.path.join(os.path.dirname(BASE_DIR), "static_cdn", "static_root")
Now, that you have done that make dir called static_my_proj, at the same level where your manage.py file is.
Okay, now create new dir called static_cdn just one level up, i.e. one level up to manage.py file.
Now, create dir called static_root inside static_cdn and that is all you have to do. Make sure you run python manage.py collectstatic
NOTE:
static_my_proj is for development or DEBUG = True and static_cdn is for production or DEBUG = True. handy, right?
Also, you can add media file the same way, just add,
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), "static_cdn", "media_root")
and make new dir called media_root under static_cdn.
EDIT:
Copy all your admin files to static dir manually.
If you have virtualenv than go to <virtualenv-dir>/lib/python3.6/site-packages/django/contrib/admin/static and copy dir named admin.
It should work even if DEBUG=False
Hope this helps.

Django Localhost not loading static files

I have a working app and have downloaded the relevant django files locally (via git) and am trying to run the app locally. However, static files are not loading.
I receive the following console error when accessing, say, the home page (http://localhost:8000/home/) of the app:
GET http://localhost:8000/static/imported_JS/jquery/jquery.min.js net::ERR_ABORTED
or this error:
http://localhost:8000/static/globe.png 404 (NOT FOUND)
In my settings.py file, I can confirm:
BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(os.path.dirname(__file__)),'..')) # i.e. location of settings.py file
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static_cdn/')
I can also confirm there is indeed a static_cdn/ file directory and it does contain the relevant static files.
The live dev and prod versions of the app work (which are hosted on separate web servers) but, for whatever reason, when running the app locally, static files are not served.
Any ideas on how to have the localhost server static files? Most of the answers on SO regarding this type of question relate to mistakes with setting up STATIC_URL vs. STATIC_ROOT but these appear to be correct (at least on dev and prod).
Let me know if you require more info. Thank you.
UPDATE
Well, I struggled with this problem for an hour or so, and 5mins after posting this SO question, I think I found a solution.
Changing from this:
STATICFILES_DIRS = []
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static_cdn/')
to this made the difference:
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static_cdn/') # add STATIC_ROOT to DIRS
]
STATIC_URL = '/static/'
# STATIC_ROOT = os.path.join(BASE_DIR, 'static_cdn/')
I'm not sure why this works but I'll indicate your response as Answer if you explain why. Thanks.

Django: Where to store global static files and templates?

So I am working on a Django (1.9) project, and have the need to use the same templates and static files across multiple apps. I know how to use templates and static files stored outside each app (using STATICFILES_DIRS and TEMPLATEFILES_DIRS in settings.py), but where should I store them?
My guess would be in folders in the project directory.
home/user/myproject/staticfiles
home/user/myproject/templates
But if there are official reconsiderations (which I have been unable to find in the documentation), I would prefer to comply with those.
Also, if there are any other recommendations for using templates and static files outside of the normal django app directories, that you think I should know about, I'd really appreciate you telling me (or telling me where to look).
Cheers :)
Assume there is a global css file located here:
home/user/myproject/staticfiles/css/global.css
Change settings.py to match this:
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "staticfiles"),
]
Inside of a template, for example, index.html:
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'css/global.css' %}" />
Now Django can find global.css.
in your settings.py file add the following
STATIC_URL = '/static/' # this will be added before your file name
STATIC_ROOT = 'path/to/your/files/' # this will help django to locate the files
read more about it here: https://docs.djangoproject.com/en/1.9/howto/static-files/
While nu everest's answer is correct and working (after you restart the server), in my case it lacks the advantage of my IDE autosuggesting the static files' paths. So I went for specifying a relative path inside my project. For simplicity I named the directory 'static' (same as the STATIC_URL variable) but of course any name is possible.
settings.py:
STATIC_URL = '/static/'
STATICFILES_DIRS = [
"myproject" + STATIC_URL
]
What's important here: The root is actually not the settings.py's parent, but its parents's parent, as in:
BASE_DIR = Path(__file__).resolve().parent.parent

How to add my own files to django 'static' folder

I've read django static files document and made my django static files settings like this
setting.py
PROJECT_PATH = os.path.realpath(os.path.dirname(__file__))
STATIC_ROOT = os.path.join(PROJECT_PATH, 'static')
STATIC_URL = '/static/'
html page
<img src="{% static "admin/img/author.jpg" %}" alt="My image"/>
So if I address one of django default static files, it works fine. But if I add my own file and folders to the static folder, it doesn't show it.
I tried
python manage.py collectstatic
But nothing changed. How can I make it work?
A few things...
STATICFILES_DIRS = (
'path/to/files/in/development',
)
STATIC_ROOT = 'path/where/static/files/are/collected/in/production'
When DEBUG = True, Django will automatically serve files located in any directories within STATICFILES_DIRS when you use the {% static 'path/to/file' %} template tag.
When DEBUG = False, Django will not serve any files automatically, and you are expected to serve those files using Apache, Nginx, etc, from the location specified in STATIC_ROOT.
When you run $ manage.py collectstatic, Django will copy any and all files located in STATICFILES_DIRS and also files within any directory named 'static' in 3rd party apps, into the location specified by STATIC_ROOT.
I typically structure my project root as such:
my_project/
/static_assets/ (specified in STATICFILES_DIRS)
/js
/images
/static (specified in STATIC_ROOT)
I hope that helps you understand how the staticfiles app works.
STATIC_ROOT is where files are collected and moved to when collectstatic runs.
If you want files to be consolidated to there they should be found by the static file finder.
As an example, include the following in your settings
STATICFILES_FINDERS = ("django.contrib.staticfiles.finders.FileSystemFinder",
"django.contrib.staticfiles.finders.AppDirectoriesFinder")
now for one of the apps that are a part of your project, create a folder called static and put something in it.
When you run collectstatic you should see that file mentioned and it copied to your STATIC_ROOT
You can try adding
STATICFILES_DIRS = (
STATIC_PATH,
)
to your settings.py.
Also, if you haven't already, make sure to include
{% load static from staticfiles %}
in each of your templates where you wish to reference static files.
Lastly, make sure that the file you are referencing actually exists and the file path to it is correct.
Try to:
<img src="{{ STATIC_URL }}admin/img/author.jpg" alt="My image"/>
And in your view must be something like this:
...
from django.shortcuts import render_to_response
from django.conf import settings
def my_view(request):
...
static_url = getattr(settings, 'STATIC_URL')
...
return render_to_response(
template_name,
RequestContext(request, {
'STATIC_URL': static_url,
}))

Handle static files in production in Django

I have two directories called media and static.
When I have DEBUG = True everything works but if I change it to DEBUG = False the problems arises.
I've read that my server will handle static files in production. I have understood it as
In development it's fine to have all my static files in my directory static but when I go in production I need to move all my static files to another directory (it could be static_www?) and before starting the server I run python manage.py collectstatic. This command will move all the files from static_www to static and everything works.
But why do I need to have two separate directories with same content? How do the server know that my files 'has been collected' through collectstatic (it's just files in a folder so how can it know the difference)? I guess collectstatic is primarily used when you have static files in multiple directories and want to collect them all before you go into production.
The variables in my settings.py looks like:
STATIC_ROOT = os.path.join(BASE_DIR, "static")
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "static_www"),
)
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
MEDIA_URL = '/media/'
and it moves from static_www to static so neither in production nor development my directory static_www is not used.
Maybe all these settings are meant for websites which has another server only for handling static files?
STATIC_ROOT is where the virtual directory for STATIC_URL will point.
Example:
STATIC_ROOT = '/var/www/example.com/static/'
STATIC_URL = 'http://www.example.com/static/'
collectstatic will find all static files in STATICFILES_DIR and copy to STATIC_ROOT.
A request to http://www.example.com/static/file.jpg will be handled by Django and /var/www/example.com/static/file.jpg will be served.
You can set your static files to be even in another site, using something like:
STATIC_ROOT = '/var/www/static.example.com/static/'
STATIC_URL = 'http://static.example.com/static/'
In this way, static.example.com can be a simple server which will serve files without they be handled by Django, increasing the site performance. Or you can upload to a CDN like Amazon S3 (and CloudFront), etc.

Categories