Several important settings in your [Django project’s
settings.py][settings] 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?
[settings]: http://www.djangoproject.com/documentation/settings/
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][__file__] to establish where on disk your `settings.py` is,
and armed with that knowledge you can construct absolute paths from the
relative settings.
[__file__]: http://www.python.org/doc/2.5.1/ref/types.html#l2h-111
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.