development with virtualenv
Posted on February 26, 2010
You should have installed virtualenv, pip, and virtualenvwrapper by now.
Boostrapping project
This section is not unique to Django projects. Any Python project can use a virtualenv like this. Creating a virtualenv is easy:
mkvirtualenv PROJECTNAME
Note this will not create a project directory. You need to do this yourself:
mkdir -p PROJECTDIR
Very often, you will like to modify PYTHONPATH to include your project directory in it. This depends on layout of your project of course. More on this later.
add2virtualenv $(pwd)/PROJECTDIR
Deactivating virtualenv
To deactivate or log out of a virtualenv, simply type:
deactivate
Or switch to another project:
workon ANOTHERPROJECT
Installing dependencies
Once you have activated your virtualenv by mkvirtualenv above or manually by
workon PROJECT
you can start installing dependencies with pip. Let's install the Django trunk with the now very popular South:
pip install -e svn+http://code.djangoproject.com/svn/django/trunk#egg=django pip install -e hg+http://bitbucket.org/andrewgodwin/south#egg=south
Make sure you check out the pip documentation for more. You may still want to and can install packages globally and the virtualenv will recognize it. The following will install PIL for example:
apt-get install python-imaging
Django project layout
Much has been written on project layout in Django projects and many exist. Here is one of them.
mysite/
docs/
resources/
myproject/
setup.py
INSTALL
AUTHORS
README
mysite is the top level project directory and can be the name of the virtualenv for clarity. It contains the django project myproject and other files and directories which do not have anything to do with Django. This extra directory (atop myproject) has been recommended by many and trust me, you will need it later as your project grows.
myproject/
settings.py
urls.py
apps/
myapp1/
myapp2/
libs/
templates/
myapp1/
myapp2/
You will see why we are having this discussion in the virtualenv article at all.
Referencing other modules
There is little confusion about how to refer to Django applications and Django parts of the code. Most projects do it like this:
from django.contrib.auth.models import User from django.contrib.contenttypes import generic from django.db import connection
Given the layout above we can refer to myprojects's objects in the same fashion:
from myproject.apps.myapp1.models import Model1 from myproject.libs.mylib import myfunc
You can clearly separate objects from either one. Of course, this means PYTHONPATH contains the path to mysite like you should have added earlier:
add2virtualenv $(pwd)/mysite
DJANGO_SETTINGS_MODULE
With the layout from above, DJANGO_SETTINGS_MODULE has to be mysite.settings. You can have virtualenvwrapper set it for you each time you switch to your virtualenv:
cdvirtualenv echo "export DJANGO_SETTINGS_MODULE=mysite.settings" >bin/postactivate