Harness contains all common settings and allows to define the very minimum required for the site to function.
Harness allows to:
- distribute INSTALLED_APPS among PROJECT_PATH/apps and PROJECT_PATH/compat folders in the project;
- specify an SQLite database filename relative to the project root;
- omit most common settings (including some of the urlconf) or easily extend them;
- use two settings files for main and local installations;
- automatically serve static, media and admin-media content in debug mode;
- easily use virtualenv with Django.
- install Harness
- create a project layout (you can just copy blank_site or example; in other cases please note that manage.py should import harness.settings_wrapper)
- run "./manage.py syncdb && ./manage.py runserver" and point your browser to http://localhost:8000/admin/ -- it works!
- start developing the site: create an application within ./apps, point to in ./settings.py (see below) and edit ./urls.py to hang your app on some URL.
To understand things better please read the following sections.
To begin with, you will probably want to explore the code including the bundled examples. Get a copy of the repository and run the setup script (which installs the "harness" module from the source tree):
$ hg clone http://bitbucket.org/neithere/django-harness/ $ cd django-harness $ sudo python setup.py install
You can omit the last step and proceed with the example without installation. Add harness package directory to the Python path (e.g. make a symlink as shown below), initialize the database and run the manager script:
$ cd example $ ln -s ../harness example $ ./manage.py syncdb $ ./manage.py runserver
There is another example, "blank_site", which can be used as a template for any website that makes use of Harness.
Another way to install/update Harness is using EasyInstall:
$ sudo easy_install -U http://bitbucket.org/neithere/django-harness/get/tip.bz2
Please note that to get most of Harness you should let it import your settings but not viceversa.
This means that manage.py should not import your project's settings.py directly; it should import harness.settings_wrapper instead, and it will import your settings.py.
Since fb7b28154379 you can also create settings for the local installation. They are stored in the file PROJECT_PATH/settings_local.py
You should exclude this file from any source control management system you may use.
The point is that you can clone a remote website repository to your computer and have all database-related and some other settings overridden so that you can immediately test the code with a local database. Then you can make changes to the code, commit them and push to the server. The local settings will never propagate to the production environment.
Applications can sit either in PYTHONPATH or in these folders within yout project:
- compat -- 3rd party applications
- apps -- your own applications and/or forks
Technically there is no distinction between these two folders save for the order. And the order is important in case you have two apps of the same name in two folders. This is not an issue, it's a feature. Imagine you have a 3rd party application sitting in the "compat" folder and you want to make some changes to it but you are not sure if they will not break something. Just fork that app to "apps" and Django will now import this copy. If things go wrong, just delete it. If everything is OK, send the patch to that app's author and wait until you can update it and delete your fork. So it's quite convenient. By the way, I usually include apps in the project repository.
Extending default settings
Harness imports your settings, so you cannot extend its defaults right in your code.
For example, this will not work (NameError will be raised):
INSTALLED_APPS = INSTALLED_APPS + ( 'my_app', )
But you can always specify additional lists by declaring "ADDITIONAL_..." variables:
ADDITIONAL_APPS = ( 'django_evolution', 'django.contrib.comments', 'my_app', ) ADDITIONAL_TEMPLATE_CONTEXT_PROCESSORS = [ 'snapboard.views.snapboard_default_context' ] ADDITIONAL_MIDDLEWARE = ( 'threadlocals.middleware.ThreadLocalsMiddleware', 'debug_toolbar.middleware.DebugToolbarMiddleware', )
This can be a bit of a problem in case of middleware. If some middleware must be put in the beginning of the list, then just declare the full list as you would do without Harness:
MIDDLEWARE_CLASSES = ( ... )
This way you can overload any variable defined in Harness.
Using automatically activated virtualenv
Add the following setting to your settings_local.py:
VIRTUALENV = '/home/andy/.virtualenvs/mysite/'
In our case this is actually a shortcut for:
VIRTUALENV = '/home/andy/.virtualenvs/mysite/lib/python2.6/site-packages/'
Harness will automatically extend the virtualenv's root path to the second form (using effective Python version) and correctly add that directory to sys.path. So you can just drop in a one-liner script (the local settings) and run manage.py without manually activating the environment. This is handy for development and essential for deployment.
The original idea was published by Frédéric Wenzel.
Where not to use Harness
If you find yourself overloading almost everything defined by Harness, or if you actually use a tiny subset of what is defined by Harness in settings or urls, then you should definitely consider sticking to the traditional way, without Harness. It was made to simplify things, not to complicate them.
An example Django project is included. It illustrates a site layout using Django Harness.