unbracketed logo and title

Use the Django Extensions

...and I should do this because:

Whenever I'm working on any Django project one of the first things I do is make sure django-extensions (formerly django-command-extensions) is available. Started by a few active community members to add in some common conveniences, it's one of the handful of tools and utilities I've come to rely on as a small time saver and probably more so a sanity saver. There's a wealth of goodies of in there and even if you only incorporate a few you'll probably end up peeking at all the various bits in there to get inspiration about solving problems in your own projects.

Even if you're working with a third-party or client site, you can still utilize the package by overriding INSTALLED_APPS in your local settings. Different folks use different conventions for handling settings overrides, with the two main camps generally being one of "main settings imports local settings" or "local settings imports main settings" but something like the following should usually work if you're in the first camp:

INSTALLED_APPS = INSTALLED_APPS + ('django_extensions',)

I like using the jobs feature for creating my maintenance and data herding scripts just because it provides the scaffolding to let me work where I'm more familiar (Python, not Bash) and keeps these scripts in their associated apps.

You create jobs for an app via the create_jobs command:

$ manage.py create_jobs myapp

Here is an example of a naive way to handle backing up your twitter updates to a local table:

from dateutil import parser as date_parser
from django.conf import settings
from django_extensions.management.jobs import BaseJob
from twitter import Twitter

from apps.status_updates.models import Status

class Job(BaseJob):
    help = "Twitter updater"

    def execute(self):
        twitter = Twitter(settings.TWITTER_USER,settings.TWITTER_PASSWORD)
        recent_updates = twitter.statuses.user_timeline()
        for tweet in recent_updates:
        try:
            status = Status.objects.get(source_id = str(tweet['id']))
        except Status.DoesNotExist:
            status = Status()
            status.message = tweet['text']
            status.source_id = str(tweet['id'])
            status.date_created = date_parser.parse(tweet['created_at'])
            status.save()
        else:
            break

Assuming I stick the above into a file _update_twitter.py _ within a jobs directory in one of my installed apps, I can run this job via:

$ manage.py runjob update_twitter

By far the features I use most often are runserver_plus and shell_plus. runserver_plus requires the Werkzeug set of WSGI utilities to be installed. When using runserver_plus you get the bonus of convenient in-browser access to the python console to examine each level of the traceback stack as well as post-mortem debugging.

shell_plus runs an initialization script when the Python shell is started to automatically load all Models from your installed apps into the global namespace. This is one of those basic things that just make life more pleasant. When combined with auto-completion features of iPython you have a powerful little playground to quickly hash out pieces of application logic or see what your models will look like under certain conditions.

With a few dozen forks of the project it seems a safe bet that the project will continue to evolve. One thing to be aware of is the createsuperuser command which allows you to create a Django admin for your site. In practice this usually won't be a problem but you may not want something like this in production environment.

blog comments powered by Disqus