What is the difference between static files and media files in Django? - python

I'm moving to Django 1.3 and find this separation of media and static files a bit confusing. Here is how default settings.py looks like:
# Absolute filesystem path to the directory that will hold user-uploaded files.
# Example: "/home/media/media.lawrence.com/media/"
MEDIA_ROOT = ''
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash if there is a path component (optional in other cases).
# Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
MEDIA_URL = ''
# Absolute path to the directory that holds static files.
# Example: "/home/media/media.lawrence.com/static/"
STATIC_ROOT = ''
# URL that handles the static files served from STATIC_ROOT.
# Example: "http://media.lawrence.com/static/"
STATIC_URL = '/static/'
What should I put into MEDIA_ROOT and a STATIC_ROOT? Should those be separate directories? What is the difference?

Static files are meant for javascript/images etc, but media files are for user-uploaded content.

As Uku Loskit said, static files are for things like your applications' css files, javascript files, images, etc. Media files are typically user or admin uploadable files.
Normally you will want MEDIA_ROOT and STATIC_ROOT to be separate directories. Keep in mind that STATIC_ROOT is where the management command collectstatic will place all the static files it finds. In production, you then configure your webserver to serve the files out of STATIC_ROOT when given a request that starts with STATIC_URL. If you are using the Django devserver for development, it will automatically serve static files.
The staticfiles application thus disentangles user uploaded media from application media, thus making deployment, backups, and version control easier. Prior to the staticfiles app, it was common for developers to have the media files mixed in with static application assets.
The 1.3 docs for staticfiles have been steadily improving; for more details, look at the how-to.

Related

dealing with static files in Django

Currently I have my settings.py regarding static files set up like so
STATIC_ROOT = ''
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
STATICFILES_DIR = (
os.path.join(BASE_DIR, 'static'),
)
STATIC_URL = '/static/'
From reading the documentation and various blogs my understanding is that STATIC_ROOT is where the static files go. It is the absolute path to the directory where collectstatic will collect static files for deployment (OUTPUT). I am not sure what to put this value as
For STATICFILES_DIR This setting defines the additional locations the static files app will traverse if the FileSystemFinder finder is enabled. So I would NEED a STATICFILES_FINDER field in my settings.py and in that field would be
('django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder')
However, by default STATICFILES_DIR is not included in my settings.py so I added it in.
For STATIC_URL is the URL to use when referring to static files located in STATIC_ROOT. I simply left it as the default setting because I am not sure how edit this.
I am not sure how to edit my settings.py regarding static files in order to display them onto a webpage. What is a "Best Practices" way to include static files onto a webpage?
ex: {% static "static/css/default.css" %}
I read a bit about namespacing as well but I am confused about this too
ex:
STATICFILES_DIR = (
("asserts", os.path.join(BASE_DIR, 'static')),
)
Best practice would be keeping each app's static files in it's own 'static' dir and running manage.py collect_static each time some static file changes.
Then, if you use default storage your files would be copied into STATIC_ROOT directory.
(But you might use custom storage, for ex for storing static files on Amazon S3 cloud)
And finally, STATIC_URL defines how your static files would be accessible from outside. In case of django dev server- it has static files app, that serves them under STATIC_URL location. In case of production server you definitely want to serve static files with either nginx/apache or with amazon S3/cloudfront (or other cloud services). In case ouf serving with nginx/apache, you must set STATIC_URL so {% static "static/css/default.css" %} will be replaced with the url relative to STATIC_ROOT, at the same time you should have this STATIC_URL location overriden in nginx/apache settings, so when final user tries to access it, it gets static file served w/o even touching django. In case of custom storage- this storage might provide it's own url (to S3 cloud for ex).

Django Static Files results in 404

Ive checked over quite a few of the other threads on being unable to serve static content using the static file app within Django but as yet have yet to find a solution.
settings.py
STATIC_ROOT = '/opt/django/webtools/static/'
STATIC_URL = '/static/'
STATICFILES_DIRS = (
"/home/html/static",
)
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
)
Template
relevant line....
<img src="{{ STATIC_URL }}macmonster/img/macmonster-logo-blue.png" >
Logs
From the logs it looks like the path is correct, but alas it is still resulting in a 404..
[10/Feb/2013 16:19:50] "GET /static/macmonster/img/macmonster-logo-blue.png HTTP/1.1" 404 1817
[10/Feb/2013 16:19:51] "GET /static/macmonster/img/macmonster-logo-blue.png HTTP/1.1" 404 1817
For local serving of static files, if you haven't set up any form of collecting of staticfiles and if you're running Django 1.3+, I believe this is the way your settings.py should look like when refering to static files
# Absolute path to the directory static files should be collected to.
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/home/media/media.lawrence.com/static/"
STATIC_ROOT = ''
# URL prefix for static files.
# Example: "http://media.lawrence.com/static/"
STATIC_URL = '/static/'
# Additional locations of static files
STATICFILES_DIRS = (
# Put strings here, like "/home/html/static" or "C:/www/django/static".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
'/Users/cupcake/Documents/Workspaces/myDjangoProject/someOtherFolderPerhapsIfYouWant/static',
)
# List of finder classes that know how to find static files in
# various locations.
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
)
Notice that I've left out the STATIC_ROOT here.
This is because I don't have the need for static files collection "just yet".
The collecting of static files is to allieviate(spelling) the problems with serving multiple diffrent staticfiles folders, so they merged the staticfiles app that was used normally for helping with this problem.
What this does, and it's described in the docs, is to take all the static files from all your apps and put them into one (1) folder for easier serving when putting your app into production.
So you're problem is that you've "missed" this step and that's why you're getting a 404 when trying to access them.
Therefore you need to use a absolute path to your static files ie. on a mac or unix system it should look something like this:
'/Users/cupcake/Documents/Workspaces/myDjangoProject/someOtherFolderPerhapsIfYouWant/static',
Also, you could simplify and "fix" the need of having a hardcoded path like that which I used for illustration and do like this
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
STATICFILES_DIRS = (
PROJECT_ROOT + '/static/'
)
This would fix the portability problem as well. A good Stackoverflow post about that is found here
I hope I made it a bit clearer, otherwise please correct me if I'm wrong ^_^!
For collecting and how to manage static files in the newer versions of Django read this link
The staticfiles app
Change
STATIC_URL = '/static/'
set
STATIC_URL = 'http://yourdomain.com/static/'
it's unbelievable but, after 1 hour searching it solution solve my problem with static files and remove STATIC_ROOT from STATICFILES_DIRS.
STATICFILES_DIRS is just for collecting all the static in modules and store it in STATIC_ROOT.

my django project static files can not be load with option debug=false

It is very strange that my django website (setup on a linux server with django 1.3) can be visit correctly with DEBUG = True. But when I changed the option to DEBUG = False the static content won't load (css files and images can not be found)
Here's related options i got in my setting.py:
DEBUG = False
STATIC_ROOT = ''
ADMIN_MEDIA_PREFIX = '/static/admin/'
STATICFILES_DIRS = ("/home/ubuntu/ls_website/static/",)
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
Anybody have any idea? If the version is too low, I would wait a while for 1.5 release.
I found when debug=False, django won't load static files automatically. Options are set static path in urls.py or serve static files with apache.
People said set static path in urls.py is slower than serve static files with apache. Don't know why though...
Staticfiles doesn't do anything when DEBUG=False. You need to serve those files with apache. Staticfiles has the ability to collect the files to one spot for you to make it easy, then you use some apache magic (assuming here since you didn't specify) to have apache intercept those requests and serve the static files for you.
Alias /robots.txt /home/username/Python/project/site_media/static/robots.txt
Alias /favicon.ico /home/username/Python/project/site_media/static/favicon.ico
Alias /static/ /home/username/Python/project/site_media/static/
I don't remember if it is buildstatic, build_static, collectstatic or collect_static to copy those files from your development stop to your deployment spot, but these variables control how staticfiles does its magic
# Absolute path to the directory that holds static files like app media.
# Example: "/home/media/media.lawrence.com/apps/"
STATIC_ROOT = os.path.join(PROJECT_ROOT, "site_media", "static")
# URL that handles the static files like app media.
# Example: "http://media.lawrence.com"
STATIC_URL = "/static/"
# Additional directories which hold static files
STATICFILES_DIRS = [
os.path.join(PROJECT_ROOT, "static"),
os.path.join(PROJECT_ROOT, "media"),
]
This assumes your static files are in the static folder of your project, and you want to serve them from the site_media folder.
I also move between Windows and Linux for development. To get around the problem of absolute paths in settings.py, I use this function:
def map_path(directory_name):
return os.path.join(os.path.dirname(__file__),
'../' + directory_name).replace('\\', '/')
Which you can implement in this fashion:
STATICFILES_DIRS = (
map_path('static'),
)
This function is tailored for Django 1.4.x. You'll need to modify it slightly for Django 1.3.x. Hope that helps you out.

Once and for all, static files vs Django 1.3

I've been trying to follow every single tutorial and thread there is, i jast cant get it togheter.
Sorry, but please exlpain it to me as if i was three years old..
What i have:
a CSS that i'd like use, styling a template.
How to get there:
MD: project/app/static/
place style.css there
settings.py:
STATIC_ROOT = '/project/app/static/'
STATIC_URL = '/static/'
(Should'nt this at least give me the string '/static/', when i try printing {{ STATIC_URL }} in the template..?)
template:
<LINK REL=StyleSheet HREF="{{ STATIC_URL }}/style.css" TYPE="text/css" MEDIA=screen>
Seems to me, the next logical thing would be to create an /static/-url aswell?
I'm really lost here..
Django's staticfiles system is about two things:
Combining static files from a number of (app-specific) directories into a single place from which they can be served
Serving those files over HTTP
You want #1 if you have a number of static files located in different directories. You want #2 if you want to see those files while you are using the development server. In production, you usually skip #2, because the purpose of #1 is to put the files somewhere that your web server can access them.
Organizing and collecting static files
With that said, here's how you get #1:
settings.py:
# This is a filesystem path
STATIC_ROOT = '/path/to/my/project/collected-static-files/'
# This is a URL prefix
STATIC_URL = '/static/'
INSTALLED_APPS = (
...
'django.contrib.staticfiles',
...
)
TEMPLATE_CONTEXT_PROCESSORS = (
...
'django.core.context_processors.static',
...
)
At this point, you can do a few things:
You put your static files in an '/static/' directory under each of your apps. That's where django will look for them. There is an additional setting, STATIC_DIRS, that you can use if you have static files that are outside of your apps.
You can run manage.py collectstatic to have Django go through all of your apps, finding all of the static files, and copying them into /path/to/my/project/collected-static-files (That's why that setting is a filesystem path.)
You can use {{ STATIC_URL }} in templates to access the files.
Serving static files over HTTP
In development mode, under the dev server, Django will automatically serve files out of the STATIC_ROOT directory.
Basically, Django will add a URL handler for URLs of the form
/static/some-dir/some-file-name
And serve content from your hard drive, from the filesystem path
/path/to/my/project/collected-static-files/some-dir/some-file-name
In production, this won't happen automatically, so you will have to configure your web server to do the same thing. (It's just not a good idea to run all of your static files through Django's full processing pipeline. The web server can do it much more efficiently)

Django static structure

I am trying to understand the static structure django 1.3 tries to pursue:
I have a Project with this structure:
Project
someapp
static
someapp
css
etcetera
models.py
views.py
urls.py
urls.py
manage.py
settings.py
Now I wish to overwrite the django admin.. So I have to set these settings in settings.py which I did like below (basepath is the shortcut path to the current directory):
# Absolute path to the directory static files should be collected to.
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/home/media/media.lawrence.com/static/"
STATIC_ROOT = BASE_PATH+'/static/'
# URL prefix for static files.
# Example: "http://media.lawrence.com/static/"
STATIC_URL = '/static/'
# URL prefix for admin static files -- CSS, JavaScript and images.
# Make sure to use a trailing slash.
# Examples: "http://foo.com/static/admin/", "/static/admin/".
ADMIN_MEDIA_PREFIX = '/static/admin/'
# Additional locations of static files
STATICFILES_DIRS = (
# Put strings here, like "/home/html/static" or "C:/www/django/static".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
)
If I use the manage.py command collectstatic, it collects all static files (including the admin files) in a directory 'static' as expected... (within the main project dir)
However it's content isn't served yet until I add that directory to the STATICFILES_DIRS tuple, however then I have to change the STATIC_ROOT directory setting because otherwise I'll get the error they cannot be the same...
I think I am overlooking the obvious because what I have to do to make it work seems redundant
For local development, try this structure
Project
Project (project directory with settings.py etc..)
stylesheets
someapp
static
base.css
With this in settings.py:
import os
ROOT_PATH = os.path.dirname(__file__)
STATIC_ROOT = os.path.join(ROOT_PATH, 'static')
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(ROOT_PATH, 'stylesheets'),
)
Run the local server with python manage.py runserver and go to http://localhost:8000/static/base.css
You should see the stylesheet.
STATICFILES_DIRS is a setting you use to declare non app-specific static files live in your project. STATIC_ROOT is where the static files get placed when they are collected.
From django's docs:
"Your project will probably also have static assets that aren’t tied to a particular app. The STATICFILES_DIRS setting is a tuple of filesystem directories to check when loading static files. It’s a search path that is by default empty. See the STATICFILES_DIRS docs how to extend this list of additional paths."
"Set the STATIC_ROOT setting to point to the filesystem path you'd like your static files collected to when you use the collectstatic management command."
How about:
STATICFILES_DIRS = (
# Put strings here, like "/home/html/static" or "C:/www/django/static".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
STATIC_ROOT,
)

Categories

Resources