Static and Media files in django 1.5 - python

I am making a site, I am the only one that will be uploading anything to the site. It seems like its more complicated to have two separate directories media and static would it be unreasonable to just funnel everything into static?
I have not yet been able to figure out how to make Django serve my static files. I'm trying to have everything on the same server but have not had any success. I have tried everything (at least I think I have) from http://djangoproject.com and I tried using this https://github.com/kennethreitz/dj-static earlier today but nothing seems to be working for me.
My settings.py file:
MEDIA_ROOT = 'media'
MEDIA_URL = '/media/'
STATIC_ROOT = '/staticfiles/'
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
My wsgi.py file
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
from django.core.wsgi import get_wsgi_application
from dj_static import Cling, MediaCling
application = Cling(MediaCling(get_wsgi_application()))

Conceptually it's better to separate static content (in /static/) from user-uploaded content (in /media/). Even if you're the only one uploading to the site. For example, if you want to make a backup of your own uploads you know that backing up /media/ is sufficient. Your static content in /static/ should hopefully be part of a version control system so you don't need to back that up separately.

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. Using .ini files in code folder

I wanted to have a .py file using a ConfigParser class to recover information from a .ini file (containing URLs for a 3rd party REST service) Until now this worked since it was finding the file, but now it's not. App structure is:
app
folder
file.py
urls.ini
I assume this is due to my static files settings, which are as following:
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_URL = '/static/'
# Extra places for collectstatic to find static files.
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
This is because I wanted to mantain settings that were compatible for both local development and web production escenarios (for which I could probably test with code in the web) for Heroku. I wanted to make it so I didn't have to change much stuff.
Thanks in advance.
If you're trying to read some files, you have to get the route.
If you have your static folder in your Django folder it could be easy to get your .ini file doing this
ini = open("%s/folder/yourfile.ini" % BASE_DIR, "r")
And then read your file lines.
In my opinion using a .py file for configuration it's easier than .ini file, and you can have many of them and load depending of a settings.py parameter for example.
Edit: for using Django config file variables
from django.conf import settings
BASE_DIR = settings.BASE_DIR

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.

Django staticfiles app help

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)

Categories