Django Scripting and the Crontab

Sometimes, you need part of your Django application to run from the command line. These scripts can be caching jobs that run periodically to speed up performance or data collection jobs that pull information from various sources into your application. Although James Bennett has a great article on writing standalone Django scripts, I just wanted to update it with changes that have happened since 2007. I ran into this problem about the same time on both a work project and on a personal project.

The problem with standalone scripts

The basic problem is that you want your script to run in the context of your application. You want to access your databases in the normal way and you want to import modules by the same paths. In general, you can do all of this work yourself by making sure your PYTHONPATH is correct and DJANGO_SETTINGS_MODULE is set properly, but it is so much easier to just create a custom management command. This is especially convenient since it makes your script portable (Windows, Mac & Linux — crontab & schedule tasks) as well easily distributable with your application.

Custom management commands

A custom management command is a command that can be run from manage.py. Essentially, Django requires that you create the following type of structure under your application:

Then, in mycommand.py you must subclass django.core.management.base.BaseCommand like so:

This will allow you to run (mycommand is named for mycommand.py):

or create a crontab entry as follows:

Conclusion

This provides the cleanest, most flexible way to build and support standalone scripts that can be used outside of the web server. It will run in exactly the same environment as your application and the same modules used in your application can be used here. The only problem I ran into was that custom management commands must be run from the same directory as manage.py.

Edit: I added thorough documentation on management commands to ticket #9170

Update: The 1.2 documentation contains the changes from my patch.