Skip to content
Using relative paths in your settings.py

Using relative paths in your settings.py

June 12, 2008

Several important settings in your Django project’s settings.py are annotated with warnings about the need for absolute path names. When I start a new project with the development server I don’t want to have to think what directory my MEDIA_ROOT should point to. Isn’t all that going to change anyway when it’s deployed to the gigantic server in the sky?

My first tip is that when you are running the development server, you can get away with relative paths. Paths will be relative to the directory you were in when you started the development server (in my case I always cd ~/my_project && ./manage.py runserver so that means relative to my project’s directory).

Therefore if you want to keep project-wide templates within the project, just create a templates directory and add it to settings.py:

TEMPLATE_DIRS = (
    'templates',
)

Sweet! Relative paths and it all works and I don’t have to edit my TEMPLATE_DIRS setting whenever I am editing on a work machine (where the project is in /Users/dbuxton/my_project) instead of home (where the project is in /Users/david/my_project).

But it all goes pear-shaped when you move the project to the deployment platform. There the project is running under mod_python where the notion of the current working directory is going to be very different. All I know is my relative paths do not get resolved and I wonder if them Django developers knew a thing or two when they warned me to use absolute paths.

My current approach to this is to refuse to do what I am told. Instead one can take advantage of a Python module’s __file__ attribute to establish where on disk your settings.py is, and armed with that knowledge you can construct absolute paths from the relative settings.

Near the top of settings.py I have:

import os

INSTALL_DIR = os.path.dirname(os.path.abspath(__file__))

Then anywhere I need an absolute path in settings.py I have something similar to this:

TEMPLATE_DIRS = (
    os.path.join(INSTALL_DIR, 'templates'),
)

Shabooba! These paths change according to the value of INSTALL_DIR, and that in turn is determined when the Django project is loaded. When my project’s templates are sitting on a distant FreeBSD server in /home/webapps/django/my_project/templates mod_python can locate them just as surely as Django’s development server can locate the folder /Users/david/my_project/templates on my MacBook.

Last updated on