One of my most popular Stackoverflow answers is to a question regarding the confusion between static and media files in Django. This post elaborates on that theme.
My most popular answer on Stackoverflow
is from a question that arose from the confusion between media &
static files in Django. As it remains popular and is still receiving
upvotes, I thought I would write it up as a full blog post.
These files can be partitioned into two families:
Our static files are a little bit more complicated. In Django we could potentially be using numerous different applications from various sources. Each of these applications might use their own static files to render any widgets or interfaces they might supply. We therefore need to be able to collect all of those scattered resources and tell Django to put them in one place so that we can serve them to the user. This is done by the built-in static files app in
This will automatically detect the absolute path to the
When a user requests a static or media file in a production environment, we want our web server (nginx/apache etc.) to deal with the request and return the file instead of passing the request down to the application server (uwsgi/gunicorn etc.). To do this we need to configure our webserver to listen for requests that match our
On the other hand, when working in a development environment, we don't want to go through the complications of having to set up and configure a fully fledged web server. Thankfully Django provide a very basic web server application that we can make use of to serve our application or site during development.
The problem is we need to specifically tell the development web server to server our static and media files. To do this we need to add some routes to our
You can see that we are telling Django to take any requests for files from our
Overview
When creating a website or web application you will most likely need to serve the user files; images, downloads, css stylesheets, javascript files etc.These files can be partitioned into two families:
- those files used in the development, creation and rendering of the website of app. Things like stylesheets, scripts, fonts etc. In Django, these are our static files
- those files that are uploaded during the normal usage of the website or application such as images, pdfs, videos etc. In Django, these are our media files
Our static files are a little bit more complicated. In Django we could potentially be using numerous different applications from various sources. Each of these applications might use their own static files to render any widgets or interfaces they might supply. We therefore need to be able to collect all of those scattered resources and tell Django to put them in one place so that we can serve them to the user. This is done by the built-in static files app in
django.contrib.staticfiles
.
You should read through the documentation as it's outside the scope of
this post, but briefly, Django provides a command to search and collect
any static files throughout your project: python manage.py collectstatic
. This will gather all of the distributed static files into a single location that can be easily served. Setup
To get our static and media files up and running for our project, there are a number of variables we need to set in our project'ssettings.py
:MEDIA_ROOT
this is the absolute path to the folder that will hold our user uploads. For exampleMEDIA_ROOT = "/User/Timmy/Sites/Pho/root/media/".
MEDIA_URL
this is the relative browser URL to be used when accessing our media files in the browser. For exampleMEDIA_URL = "media/"
STATIC_ROOT
this is the absolute path to the folder within which we want our static files to be collected by thestaticfiles
application. For exampleSTATIC_ROOT = "/User/Timmy/Sites/Pho/root/static/"
STATIC_URL
likeMEDIA_URL
, this variable is the relative browser URL to be used when accessing our media files in the browser. For example `STATIC_URL = "static/"
Tip
Don't manually set the absolute paths for your static and media folders. Instead, you can do the following:This will automatically detect the absolute path to the
settings.py
file and then append media/
to it given you a dynamically generated path to your media root. Deployment & Serving
Now that we have told where Django can find our various files as well as the URLs they can be located under, we need to actually serve the files for incoming requests. Generally there are two possible scenarios; a production or development environment.When a user requests a static or media file in a production environment, we want our web server (nginx/apache etc.) to deal with the request and return the file instead of passing the request down to the application server (uwsgi/gunicorn etc.). To do this we need to configure our webserver to listen for requests that match our
STATIC_URL
and MEDIA_URL
and return the files immediately from the STATIC_ROOT
and MEDIA_ROOT
folders. How we go about configuring this is outside the scope of this post. On the other hand, when working in a development environment, we don't want to go through the complications of having to set up and configure a fully fledged web server. Thankfully Django provide a very basic web server application that we can make use of to serve our application or site during development.
The problem is we need to specifically tell the development web server to server our static and media files. To do this we need to add some routes to our
urls.py
:from django.conf import settings
if settings.DEBUG:
urlpatterns += patterns('',
url(r'^media/(?P.*)$', 'django.views.static.serve', {
'document_root': settings.MEDIA_ROOT,
}),
url(r'^static/(?P.*)$', 'django.views.static.serve', {
'document_root': settings.STATIC_ROOT,
}),
)
MEDIA_URL
and STATIC_URL
, look for them in MEDIA_ROOT
and STATIC_ROOT
and serve them.django-filebrowser and grapelli
django-grappelli
provides a revamp of the existing django admin look-and-feel. In
itself, it simply makes your site look better – you’ll need this in case
a site also needs to provide admin access to the product owner. For
this case, however, we’re using grappelli as a dependency for
django-filebrowser.
django-filebrowser does exactly what its name says. In a nutshell, django-filebrowser lets you navigate through and manipulate your media files through your django admin site. This is useful should you eventually need the end-user to be able to control image files without having to dig deep into the server’s internal filesystem.
First, make sure the dependencies are installed. PIL may prove tricky to install, but from there it’s all simple.
Note: the PROJECT_ROOT style makes your settings more portable, so it’s a good habit to start.
Next, we make a symbolic link to the grappelli media folder (in site-packages) from your project media folder.(In the directory defined by MEDIA_ROOT)ln —symbolic /PATH/TO/site_packages/grappelli/media grappelli
Then, make sure your installed apps has this order:
Same goes for your urls,
(In the directory defined by MEDIA_ROOT)
Indicate in additional settings using this as reference:http://code.google.com/p/django-filebrowser/wiki/Settings
Once you’re set up, check it out with the following url:/admin/filebrowser/browse/ django-filebrowser does exactly what its name says. In a nutshell, django-filebrowser lets you navigate through and manipulate your media files through your django admin site. This is useful should you eventually need the end-user to be able to control image files without having to dig deep into the server’s internal filesystem.
First, make sure the dependencies are installed. PIL may prove tricky to install, but from there it’s all simple.
- pip install django==1.2
- pip install PIL==1.1.7
- pip install django-grappelli=2.1
- pip install django-filebrowser==3.1
Next, we make a symbolic link to the grappelli media folder (in site-packages) from your project media folder.(In the directory defined by MEDIA_ROOT)ln —symbolic /PATH/TO/site_packages/grappelli/media grappelli
Then, make sure your installed apps has this order:
No comments:
Post a Comment