Django development on OS X using a local media server

Update: Eric Moritz has pointed out to me that Django provides an easy way to do this already. See How to serve static files.

For a long time now, I’ve been uploading CSS and image changes to an FTP server every time I wanted to change the look and feel of a locally developed Django app, and used an HTTP path in my MEDIA_URL setting. It wasn’t until this week that I found an effective way to host static media from outside of Django while developing locally. For some, this solution will be rather obvious. For anyone else, I hope this helps your workflow like it helped mine.

Step 1: Turn on OS X’s built-in Apache server

Open your System Preferences, and select the “Sharing” preferences. Click the check box next to “Web Sharing” to turn on the built-in Apache web server. When this box is checked, visiting http://localhost/~yourusername/ in a web browser will show the files from the “Sites” folder inside your user’s home folder.

Step 2: Set your Django project to use your local URL for media

In your projects settings.py file, create a folder called (yourprojectname), then set:

1
MEDIA_URL = "http://localhost/~yourusername/yourprojectname"

Step 3: Use MEDIA_URL in your templates instead of full paths

When MEDIA_URL is set in your settings.py file, Django provides adds a {{ MEDIA_URL }} variable to the context for each request on your site:

1
2
3
<link href="{{ MEDIA_URL }}/css/base.css" rel="stylesheet" type="text/css" />

<img src="{{ MEDIA_URL }}/img/picture.jpg" alt="Picture" />

Step 4: Make a folder for media inside your project

Create a folder named ‘media’ inside your project folder, then use dynamic paths in your settings.py to make deployment easier

1
2
3
4
5
6
# Store the path to the project folder in a variable for repeated use
import os
project_path = os.path.dirname(__file__)

# Set the media root as the folder named 'media' inside the project folder
MEDIA_ROOT = os.path.join(project_path, 'media')

Step 5: Point MEDIA_URL to MEDIA_ROOT

Since OS X’s Apache server looks in ~/Sites/ for files, but media is hosted elsewhere inside the Django project, the two need to be connected. In your terminal, make a symbolic link (also known as an alias) from ~/Sites/yourprojectname/ to the Django project:

1
ln -s /path/to/your/project ~/Sites/yourprojectname

To confirm this has worked, open your ~/Sites in the Finder and you should see a folder with an arrow, indicating an alias, labeled with your project name. Click on the alias and you’ll see the contents of the media folder inside your project. Fire up your Django development server, and you’re ready to go.

For more information on Django’s development server, visit the docs


Discussion
Link to this comment

Couldn't you use the Django dev server to do this in development? http://docs.djangoproject.com/en/dev/howto/static-files/

October 27th 2008, 3:08 p.m. by AlastairC
Link to this comment

AlastairC - Yeah, I posted an update atop the post with the link. For some reason I'd never read that doc page before.

October 27th 2008, 3:14 p.m. by Ryan Berg
Link to this comment

A third way to do it is to simply tempoarily start a python http server in the media folder:

python -m SimpleHTTPServer

Then, you can access the media server at localhost:8000

October 27th 2008, 4:33 p.m. by David
Link to this comment

By using the Django dev server is a better solution, but still thanks for your tip.

October 27th 2008, 10:27 p.m. by omtv
Link to this comment

David - I never knew about that command. Thanks!

October 27th 2008, 11:09 p.m. by Ryan Berg
Link to this comment

Actually... I often use OS X's built-in Apache, and I think I've mentioned this once or twice in my own blog posts. There are a couple reasons why I prefer this method:

  • Doing this with Apache requires you to do the setup once; after Apache's running, you just drop files into the right directory and it works. Doing it through the dev server or a Python-based simple web server requires configuring it every time I set up a new project.
  • Django's built-in dev server is deliberately very simple and deliberately not optimized for performance. One of the optimizations it doesn't have is multithreading, which means it can only handle one HTTP request at a time, so if you have, say, a page which pulls in a stylesheet, a couple JavaScript files and some images, you have to wait while the dev server handles them one at a time, which just isn't any fun at all. Meanwhile, Apache's really good at concurrent serving, and frees up Django to do, well, Django.

So if you're on OS X, I recommend using the built-in Apache for media: it's simpler and you'll probably see faster responses during development.

October 28th 2008, 8:51 p.m. by James Bennett
Link to this comment

James - Sounds like I should have named this "Django development on OS X using a local multithreaded media server" to prevent any comments about overlap. Thank you for clarifying the differences between using Django's dev server and using Apache. Though the Apache way, if you're wanting to keep your files contained in one place, still requires configuration of symbolic links.

October 29th 2008, 12:09 a.m. by Ryan Berg

Comments are disabled for this item