Django just isn’t designed to run under CGI.
It won’t run under OS/2, either.*
Well ok, but running Django under CGI is not impossible. It just kind of really sucks. But anyway, to prove it’s possible if not workable, here’s how I got it running on two standard cPanel shared hosts using plain old slow and clunky CGI.
First, install virtualenv. This makes locally managing modules fantastically easy by creating self-contained Python virtual environments. Installing couldn’t be simpler: Get the script, run the script, source your environment.
$ mkdir ~/src && cd ~/src $ curl -LO http://bitbucket.org/ianb/virtualenv/get/tip.gz $ tar -xvzf tip.gz $ python virtualenv/virtualenv.py --distribute ~/python_virtualenv New python executable in /home/joe/python_virtualenv/bin/python Installing distribute............................................. ..................................................done. $ source ~/python_virtualenv/bin/activate
Now, install Django using pip, which was automatically installed by virtualenv. After sourcing the virtual environment, this works from anywhere.
$ pip install Django Downloading/unpacking Django Downloading Django-1.1.1.tar.gz (5.6Mb): 5.6Mb downloaded Running setup.py egg_info for package Django Installing collected packages: Django Running setup.py install for Django changing mode of build/scripts-2.4/django-admin.py from 664 to 775 changing mode of /home/joe/python_virtualenv/bin/django-admin.py to 775 Successfully installed Django
If your host doesn’t block GCC, use pip to be sure your MySQL interface (MySQLdb) is up to date:
$ pip install -U MySQL-python ... Successfully installed MySQL-python
Django requires MySQLdb version 1.2.1p2 or higher.
Yolk prints a nice, clean list of everything installed in your Python environment, install and run:
$ pip install yolk $ yolk -l Django - 1.1.1 - active MySQL-python - 1.2.3c1 - active pip - 0.6.1 - active setuptools - 0.6c11 - active yolk - 0.4.1 - active
At this point, I started a new Django project, assigned a database and filled in the necessary values in settings.py. I put the Django project files into the virtual environment to keep everything in the same place. This might not be the best practice, but it makes sense to me.
$ cd ~/python_virtualenv/ $ django-admin.py startproject testproject
The sane part is finished, now onto the kludgery.
All the CGI shim solutions I found pointed back to a script Paul Sargent uploaded to ticket 2407 back in summer of 2006. It still works: django.cgi
Three lines need editing:
Line 1: Point the CGI’s shebang to the virtualenv Python binary.
Line 95: Add the directory above the Django project directory to Python’s sys.path.
Line 97: Add the project’s settings to os.environ.
os.environ['DJANGO_SETTINGS_MODULE'] = 'testproject.settings'
For Django to respond to URL requests, those urls need to be fed into the django.cgi script. For testing I routed everything from /django to the cgi script by adding the following lines to my top-level htaccess file:
RewriteEngine on RewriteRule ^cgi-bin/ - [L] RewriteRule ^django/(.*)$ /cgi-bin/django.cgi/$1 [QSA,L]
The second line isn’t necessary unless pulling Django urls from the webroot, without it, the redirects would loop.
At this point, the Django site should load from /django/… urls.
Finally, as a quick fix for admin media files, I symlinked Django’s admin media directory from my web root:
ln -s ~/python_virtualenv/lib/python2.4/site-packages/django/contrib/admin/media ~/www/media
I spent quite a few hours spread across a couple days researching and figuring out how to get the first install working. The second installation only took about 5 minutes from start until editing Django’s admin pages.
Running Django through CGI is possible, but it is dog slow. There appears to be some caching after the first request, but that first page load often takes an excruciatingly long time.
Further reading, possible improvements
- 21.4. wsgiref — WSGI Utilities and Reference Implementation — Python v2.6.4 documentation
- Django snippets: django under apache / mod_fcgid
The servers I was working with are both running the almost six year old Python 2.4.3. The wsigref module was introduced with Python 2.5. My goal was to get Django running without compiling anything since some hosts deny access to GCC.
These sites were helpful in figuring this out.
- Notes on using pip and virtualenv with Django « SaltyCrane Blog
- JeffCroft.com: Setting up Django on Dreamhost
- seamusc.com – How to get Django working on digiweb.ie using django.cgi
- Lithium Hosting – Knowledgebase – How to install Django on a basic shared hosting plan with plain CGI
- Django revisited – PeterSmith: Blog