Serving Files Controlled by Django with NginX

21 Jun 2012

The following post is related to a Nginx/Apache2/Django stack as described in this article...

If you ever need to serve files, of course you shouldn't use Django to do it! It's common knowledge on how to setup static files with Nginx, but what about if you would offer file downloads that are access controlled by Django? (In my case, I had network shares that were required to be accessible from the Django application to serve to users, but still hidden from the world.)

Well it's easy with django-sendfile and Nginx!

What you are basically doing is taking advantage of Nginx's "X-Accel-Redirect" which is similar to lighthttpd's X-Sendfile and Apache2's mod_xsendfile. The library just abstracts the work a little bit, and makes it easy to drop in backends for different environments.

First install django-sendfile and create all the views you need, etc. It's very straightforward to use and sufficiently documented.

Then just add the following to the proper sites-available file in nginx:

location /files {
	alias /path/to/files;

Which will serve the URI /files/goop/foo.jpg the file /path/to/files/goop/foo.jpg or you can use:

location /files {
	root /path/to/files;

Which will serve the URI /files/goop/foo.jpg the file /path/to/files/files/goop/foo.jpg

Since this rule is internal it will not respond to any other request but from your Django application. Upon receiving the X-Accel-Redirect header from the Django app it coughs up the file, sidestepping Django and keeping things snappy.

Now you can control downloads served through Nginx with Django!