I'm somewhat confused as to what the difference is between STATIC_URL and STATIC_ROOT in Django's 'staticfiles' app.
I believe I understand what the STATIC_ROOT is: it's essentially the location on the server where the staticfiles' collectstatic command will place the static files collected from your django project. The collectstatic command searches in the locations that you specify in the STATIC_FINDERS setting.
However, what exactly does the STATIC_URL do? What should this be set to? Apparently it's intended to be set something such that users can access static files. But what is it's relationship with STATIC_ROOT?
Why is the default value of STATIC_URL simply /static/ ? Does STATIC_URL have to be able to reference STATIC_ROOT?
Like you mentioned, it is pretty clear from the documentation:
STATIC_ROOT:
The absolute path to the directory where collectstatic will collect static files for deployment.
STATIC_URL
default: None
URL to use when referring to static files located in STATIC_ROOT.
Example: "/static/" or "http://static.example.com/"
While, the STATIC_ROOT is just the path to the directory where static files have been collected, STATIC_URL is the URL which will serve those static files.
And, as you can see in the example, you can define STATIC_URL as a subdomain "http://static.example.com/" and when you use it in the template:
<link rel="stylesheet" href="{{ STATIC_URL }}css/base.css" type="text/css" />
It will be treated as:
<link rel="stylesheet" href="http://static.example.com/css/base.css" type="text/css" />
But, if the STATIC_URL was just /static/ then the above link would point to:
<link rel="stylesheet" href="/static/css/base.css" type="text/css" />
And, since this href starts with / it will append your domain to access the static files: http://yourdomain/static/css/base/css
Why is the default value of STATIC_URL simply /static/ ? Does STATIC_URL have to be able to reference STATIC_ROOT?
Default value of STATIC_URL is not /static/ but None as you can see in the documentation. And, it doesn't have to reference to STATIC_ROOT because it is not dependent on it (as shown in the example above).
STATIC_URL is simply the prefix or url that is prepended to your static files and is used by the static method in Django templates mostly. For more info, read this.
STATIC_ROOT is the directory or location where your static files are deployed when you run collectstatic.
So, when you have STATIC_URL defined as /static/, then your users would request static files from /static/file-name.example (a relative URL on your server).
If you had customized your collectstatic to deploy static files to another server, you could set STATIC_URL to https://static.example.org/.
Then, you'd access your files at https://static.example.org/filename.ext.
Another example I have is using the Boto S3 library to upload static and media content to Amazon S3. My STATIC_URL looks like this:
STATIC_URL = '//%s/%s/' % (CLOUDFRONT_DOMAIN, STATIC_S3_PATH)
It constructs a static URL prefix like this //mycloudfront.whatever/static/ so users will be served files from our CDN.
My STATIC_ROOT however is defined as:
STATIC_ROOT = '/%s/' % STATIC_S3_PATH
...because I need to upload my content to Amazon S3 and not Cloudfront.
STATIC_ROOT is where all your assets will be collected by the collectstatic command. The contents of this directly contain all static assets from all applications listed in INSTALLED_APPS (from their own static folders) and any file locations mentioned in STATICFILE_DIRS.
Once you have collected all these assets, in order for django to create urls you need to tell it what is the base URL to these assets, that's the STATIC_URL setting, and it must always end in a slash.
Related
According to step 4 in Django's Static Article, best practise is to set up your app's static tree structure as such:
my_app/static/my_app/example.jpg
...in order to mitigate duplicate/naming issues when you later run collectstatic as two apps COULD have the same named static files.
So how do I set up my app's settings and templates to allot for this kind of structure? Right now, I just have a static folder within each app, and my files inside it. I have my settings.py as such:
# Absolute filesystem path to the directory that will hold user-uploaded files.
# Example: "/home/media/media.lawrence.com/media/"
MEDIA_ROOT = str(BASE_DIR) + "/media/"
# 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 = '/media/'
# Absolute path to the directory that holds static files.
# Example: "/home/media/media.lawrence.com/static/"
STATIC_ROOT = str(BASE_DIR) + "/static/"
# URL that handles the static files served from STATIC_ROOT.
# Example: "http://media.lawrence.com/static/"
STATIC_URL = '/static/'
...and my templates that import from their respective static folders looks like this:
<link rel="stylesheet" href="{% static "style.css"%}" />
In order to implement what the article says, do I have to go into each app's template and change the above line to something like:
<link rel="stylesheet" href="{% static "my_app/style.css"%}" />
...or is there a way to set it up something like:
<link rel="stylesheet" href="{% static % MY_APP "style.css"%}" />
Seems kinda messy to have a "my_app" folder, inside the "my_app/static" folder, but I guess I get the logic for saving a mess later. Looking for the best way to do this.
Here's my script in base.html, the left of the picture is about my tree.
I checked the href should be correct and I've load static at very top of the html file. However I still cannot connect the css file anyone can help he here? Thanks!
href="{% static 'Simple_Social/css/master.css' %}"
for refer, please see the picture since idk why I can't post a picture yet, thanks!
https://i.stack.imgur.com/Vi2z6.png
This is how static files are configured. In settings.py file inside the INSTALLED_APPS list, there is an app called 'django.contrib.staticfiles', this baked in app manages the static files across the entire project during development as well in production.
This static URL will append to base URL for serving static files in development like http://127.0.0.1:8000/static/css/style.css basically think this as a reference to static files.
STATIC_URL = '/static/'
STATICFILES_DIRS tells Django the location of static files in our project. The common practice is to have all the static files in a top-level static directory.
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static'), ]
STATIC_ROOT is the single root directory from where the Django application will serve the static files in production. The command manage.py collectstatic will automatically compile all the static files throughout the project and dump it into a single root directory, which is declared in STATIC_ROOT.
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
Finally, you can user load static to load the static files in template
{% load static %}
In the documentation https://docs.djangoproject.com/en/dev/howto/static-files/
I read that static files should be put with their respective apps and called upon with
{% load staticfiles %}
<img src="{% static "articles/css/base.css" %}" alt="My image"/>
However later on in the docs it mentions that some static files don't pertain to a particular app. This is where STATICFILES_DIRS comes into play. If I read correctly STATICFILES_DIRS is a tuple for Django to use to look for other static files. I was wondering how would I call the static files that was called from the STATICFILES_DIRS?
ex: something like
<link rel="stylesheet" type="text/css" href="{% static "/css/default.css" %}">
Also I am not sure what to put for my STATIC_ROOT. Do I leave it empty? ('')
My proj tree
mysite
\articles
\static
\articles
\css
base.css
\static
\images
\css
default.css
\js
\templates
base.html
\settings.py
This is currently in my settings.py regarding static files
# looks for static files in each app
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
STATICFILES_STORAGE = (
'django.contrib.staticfiles.storage.StaticFilesStorage'
)
# the absolute path to the directory where collectstatic will collect static files for deployment (OUTPUT)
STATIC_ROOT = ''
# This setting defines the additional locations the static files app will traverse if the FileSystemFinder finder is enabled.
STATICFILES_DIRS = (
# used for static assets that aren't tied to a particular app
os.path.join(BASE_DIR, 'static'),
)
# URL to use when referring to static files located in STATIC_ROOT
STATIC_URL = '/static/'
Almost everything about django static is related to the django.contrib.staticfiles app. Although you need to custom edit many settings to make staticfiles work, what is does is simple. It provides a collectstatic command which collects static files from different app and put them into a single directory.
The answer to your first question is simple: Put those common static files under the /static directory of your django project directory. In your case, it's mysite/static.
Reason: First, it's the official way. You can find the following code in official doc: Managing static files (CSS, images). Second, it's reasonable. Since we put static files only used in a single app under project/appnane/static/... The project's static dir should follow the same name pattern.
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "static"), # That's it!!
'/var/www/static/',
)
As I said in the comment, your should not set STATIC_ROOT to project_absolutr_path/static. Because that directory is user to put css app static files. You don't want the collectstatics command to pollute that directory especially when you are using a version control system like git/svn.
STATIC_ROOT really depends on the way you host these static files(Apache, Nginx, S3, CDN, Paas like heroku)
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).
I have downloaded a template online that includes a base html file, images and a css file. Now I would like to implement all this in django.
So far I tried like this but with no good results, the page gets rendered without css file or without images, or both... well something is wrong
settings.py:
MEDIA_ROOT = rel('resources')
MEDIA_URL = '/resources/'
base.html:
<link rel="stylesheet" type="text/css" href="resources/style.css" />
I have put my images and the css file in the resources folder and the templates folder and it doesnt work, please help
EDIT:
I was slightly off there... STATIC_ROOT refers to the directory where Django will collect all static files. STATICFILES_DIRS is a list of searchpaths for static files. So like this:
settings.py:
# 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 = PROJECT_ROOT + 'static/'
# 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.
"C:/www/django/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',
)
and add the url to urls.py:
urlpatterns += staticfiles_urlpatterns()
ORIGINAL ANSWER:
This can be quite confusing.
The MEDIA_ROOT directory is for files uploaded via a file-upload form. For physical files that are directly accessible by client request (e.g style sheets, scripts and images) you have to use the STATIC_ROOT and STATIC_URL. STATIC_ROOT must be an absolute path i think.
settings.py
# the url: myserver.com/static/
STATIC_URL = '/static/'
# refers to this directory:
STATIC_ROOT = '/home/user/static server files'
let's say you put your css in "/home/user/static server files/css/" then refer to them like this:
base.html
<link rel="stylesheet" href="{{ STATIC_URL }}css/style.css" />
Assuming you are working on a development server for now .
MEDIA_URL = 'http://localhost/media/'
calculated paths for django and the site
used as starting points for various other paths
DJANGO_ROOT = os.path.dirname(os.path.realpath(django.__file__))
SITE_ROOT = os.path.dirname(os.path.realpath(__file__))
PROJECT_ROOT = os.path.dirname(__file__)
TEMPLATE_DIRS = (
os.path.join(SITE_ROOT, 'templates/'),
)
MEDIA_ROOT = os.path.join(SITE_ROOT, 'templates/media/')
The above should solve your problem as iot worked for me just fine.
While referring css files which are kept in "templates/media"
<link href="/media/css/base/base.css" rel="stylesheet" type="text/css"></link>
Hope this helps you out
hmm unfortunately this did not help. I could not find a variable STATIC_URL/ROOT in settings.py, so I added it as described above, also added the variable in base.html, but rendering still cannot find css file.
Another this I did is investigated code that works. I got a piece of good public application's source code and inspected base.html, and it says like this:
<link rel="stylesheet" href="{{ cssRootUrl }}style.css"
then I went to check the settings.py and cssRootUrl was not defined there. So I have no idea where else could this kind of variable hide...
this can solve your problem. I suggest you name your folder "static" for static files that you are using (css, js and images).
open your settings.py and
-add this at the first line of your file:
import os.path
-change your STATIC_ROOT's value to:
STATIC_ROOT = os.path.join(PROJECT_DIR, 'static/')
-change your STATIC_URL's value to:
STATIC_URL = '/static/'
create a folder named "static" in your project root.
create a folder for your static files like css, javascript and etc. I recommend you use a different folder for different types of files.
open the urls.py of your project
-add this to your imports: import settings
-add this to the url patterns:
(r'(?:.*?/)?(?P(css|jquery|jscripts|images)/.+)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT }),
NOTE: In this example, there are folders named css, jquery, jscripts and images inside my static folder.
In your template add this:
for css files: (in this example, default.css is the name of the css file)
<link href="/{{ STATIC_ROOT }}css/default.css" rel="stylesheet" type="text/css" media="all" />
for javascript:
<script type="text/javascript" src="/{{ STATIC_ROOT }}jquery/jquery.js"></script>