Django?s development server is capable of serving static (media) files thanks to the view django.views.static.serve. Popular web servers like Apache, Lighttpd or NGINX are much faster though, and as such should be used in production mode. Our goal is to bypass Django and let Apache (or other valid alternatives) directly serve static files like images, videos, CSS, JavaScript files, and so on, for us.
Generally speaking, for performance reasons, it?s advised that you have two different webservers serving your dynamic requests and static files. In practice, for smaller sites, people often opt to simply use one webserver. In this article, I?ll discuss how to serve the static files within your Django project, through Apache.
The first thing we need to do is distinguish between development and production mode. We can do so by simply specifying DEBUG = True (development), or DEBUG = False (production) within our settings.py file.
settings.py may include (among others) the following declarations:
*PATH constants indicate paths on your filesystem (e.g., /home/myuser/projects/myproject), while *URL constants indicate the actual URL needed to reach a given page or file.
Notice that it?s not unusual to have a /site_media URL that corresponds to a /media folder. In the example above, I opted to separate regular media files for the project from the standard ones that ship with Django for the admin section. To do this, all we have to do is create a symbolic link as follows:
When you?re in development mode, and DEBUG = True, you want to let Django serve your static files. This can be done by adding the following snippet (or similar) to your urls.py:
In production mode, the code contained within the if clause will not be executed as we?ve set DEBUG to False within settings.py.
From the Django side of things, we are good. We now need to instruct Apache. Within your virtual host file, you can specify something along the lines of:
The first group of declarations essentially tells Apache to use mod_python to handle any incoming requests. However, we don?t want Django to deal with static files, so the second group of declarations, aliases/maps the /site_media URL with the actual media directory on the server, and tells Apache to threat it as static content (with SetHandler None) bypassing de facto Django.
Possibly related posts:
- Installing Django with PostgreSQL on Ubuntu
- How to install Django with MySQL on Mac OS X
- A step by step guide on how to install Django with PostgreSQL on Windows
- Django is great
- Django turns 1.0
If you enjoyed this post, then make sure you subscribe to my Newsletter and/or Feed.
11 Responses to ?Serving Django Static Files through Apache?
Legal | Politics | Sports | Teens | Webmasters
Source: http://programmingzen.com/2009/07/22/serving-django-static-files-through-apache/
lighting and lamp fine art lamps lighting art deco wall lights art deco ceiling lights uttermost lighting
Nice to see this piece of information in such a clear way.
Tks for the tip.
You can try http://www.cherokee-project.com it?s an amazing webserver ..
Yes, Leonel. Cherokee is awesome.
I fail to see the point in the ?if settings.DEBUG? statement in urls.py since the webserver will already be taking care of things before you get there in production?
Also ?MEDIA_ROOT = ?%s/media/? % BASE_PATH? should probably be ?MEDIA_ROOT = os.path.join(BASE_PATH, ?media?)? if you want to be os agnostic.
sorl, if Apache is misconfigured, checking for settings.DEBUG ensures that the files aren?t being served by Django. Regarding your second point, this article is clearly aimed at *nix systems (you wouldn?t do ln -s on Windows either).
Ironically if you are unsure if your production environment is set up properly you might want to set DEBUG to True. Perhaps using a similar ?trick? to http://www.djangosnippets.org/snippets/644/ for urls is a better idea (import local_urls?)? As for point #2: There are absolutely no reasons not to use os.path.join
sorl, while I don?t think it?s a big deal, I agree that using os.path.join is probably better.
I totally agree its not a big deal.. its just annoying to see that if statement since it doesn?t do much good, do you know any other blog posts I can spam?
Does it also work this way when I want to display pictures in MEDIA_ROOT on a webpage?
I?ve tried this and don?t find the error ? but don?t see a picture ? *sigh*
In the webpage I have:
<img src="
http:///zooscan/profilepics/PIC.png ? />
Thanks for any hints!
Thanks so much! This was just what I was looking for. Django is awesome, but this is its one Achilles heel so far.
Thanks so much, Antonio!