Saturday, March 10, 2007

Django mysite.settings madness

For fun, I've started writing a small firewall (meaning OpenBSD PF) monitoring webapp using Django, which I actually will be blogging on it real soon now -- but first on something that seemed rather confusing about the framework, and that has tripped up others as well.

In recent (at least 0.95 and 0.95.1 but probably much earlier) you don't actually have to set the environment variable DJANGO_SETTINGS_MODULE if you running the webserver with python manage.py runserver or access a shell with python manage.py shell, but you still have to set this enivironment variable -- or call settings.configure() -- if you are access any of your Django objects from another app.

While this is clearly documented on the web site, it still gives newbies trouble, especially when running Django with mod_python under Apache. In fact a couple of months ago it stumped me for a while,.

However, what was most confusing is that everywhere (in most of the examples) the variable is always defined to mysite.settings but it is ambigous what the "mysite" should be. Is mysite my actuall site (or project) or is it always set to mysite and Django knows automatically. So settings the settings.py that gets imported by your scripts, but is mysite a path name?

If I used the value "mysite.settings", I get the following:

franz-g4:~/Documents/dev/playin/pfwatch mdfranz$ export DJANGO_SETINGS_MODULE=mysite.settings
franz-g4:~/Documents/dev/playin/pfwatch mdfranz$ python shellstuff.py
Traceback (most recent call last):
File "shellstuff.py", line 4, in ?
from monitor.models import Source,Event
File "/Users/mdfranz/Documents/dev/playin/pfwatch/../pfwatch/monitor/models.py", line 1, in ?
from django.db import models
File "/opt/local/lib/python2.4/site-packages/django/db/__init__.py", line 7, in ?
if not settings.DATABASE_ENGINE:
File "/opt/local/lib/python2.4/site-packages/django/conf/__init__.py", line 27, in __getattr__
self._import_settings()
File "/opt/local/lib/python2.4/site-packages/django/conf/__init__.py", line 52, in _import_settings
raise EnvironmentError, "Environment variable %s is undefined." % ENVIRONMENT_VARIABLE
EnvironmentError: Environment variable DJANGO_SETTINGS_MODULE is undefined.

To back up a bit, I have the following files in my project directory:

franz-g4:~/Documents/dev/playin/pfwatch mdfranz$ ls
__init__.py manage.py pfwatch.sql settings.pyc urls.py
__init__.pyc monitor settings.py shellstuff.py urls.pyc
franz-g4:~/Documents/dev/playin/pfwatch mdfranz$

So monitor is an application directory where I have my models defined and shellstuff.py is a script that I want to be able to access my models, meaning my data, which fails if I use mysite.settings. It also fails if I use pfwatch.settings both from within the current directory or if I step up a level.

So how did I finally get it sort of working? The solution is just to set DJANGO_SETTINGS_MODULE to just settings.

Of course this blog entry will make a lot more sense once you read my next one.

1 comment:

norslack said...

Had the same problem. This fixed it, thanks! Why does this has to be so confusing? Surely there is a better way. Looking forward to be using Django.