Django plugins you shouldn't start without

Sometimes there are tools out there that could make your life a lot easier but you just don't know about them. Here, I'm going to share 5 django apps that you should be using.

django-extensions

Documentation: http://django-extensions.readthedocs.org/en/latest/
Video demo: http://vimeo.com/1720508

Django Extensions, amongst other things, provides extra management commands to make your life easier. Here are a few commands to illustrate that.

export_emails

Allows you to export your users email addresses. You can specify some arguments to change the output type.

graph_models

This automatically generates an image of how your models look and how they relate to each other. This is an excellent tool that you can use to learn about the relationships of different built-in models. It also works great for documenting and communicating your design to other people visually.
Here is what graph_models generated for all the models in my Hacker News digest service (this includes the django models as well):

runserver_plus

This command runs the test server. Why would you do that? Well, how would you like to inspect the state of your code right in your browser when an error happens? Yup, it's that amazing.

runscript

This allows you to run any regular python script from the command line that relies on the django context (your models, for example).

shell_plus

If you've ever run ./manage.py shell, it's probably because you want to work with your models and other django libraries. shell_plus automatically imports all your models!

That's not all.

Those are just command extensions to manage.py. django-extensions also provides field extensions, and admin extensions. For example, one extra field that can be used is CreationDateTimeField which is a DateTimeField that will automatically set an object's date when it's first saved. Handy!

sekizai

Documentation: http://django-sekizai.readthedocs.org/en/latest/

Sekizai, which apparently means 'blocks' in Japanese, adds flexibility to Django's template blocks. It's especially useful for JavaScript and CSS. Here's an example.

With sekizai, you define where your block content will be rendered, like so:

...
{% render_block "css" %}
...

And then you can add to that block. This can be done in the same template, an included template or templates that extend the current template. Like so:

{% addtoblock "css" %}
   <link href="/media/css/stylesheet.css" media="screen"
   rel="stylesheet" type="text/css" />
{% endaddtoblock %}

The nice thing is that if you addtoblock the same style sheet twice (say, because you didn't realize it was already added in an included template), it's no problem. Sekizai only renders that sheet once no matter how many times you add it.

reversion

Documentation: http://django-reversion.readthedocs.org/en/latest/

django-reversion is an excellent plugin, especially if you're building websites for clients. If you're using django's admin module, your users can change model objects, save them and view the history of those object and even revert back to a specific version. You get all this by simply inheriting from reversion.VersionAdmin in your admin class.
django-reversion history

South

Documentation: http://south.readthedocs.org/en/latest/

When I started my first Django project, I had created my models and had them just the way I wanted. Mind you, this did take sometimes me logging into my database and just dropping a table because I needed to change the model. Dropping tables, of course, stops being an option as soon as you're dealing with real data in production. So, let's say you have a model called Post (this is the real model I use to store stories I scrape from Hacker News for HNdigest):

class Post(models.Model):
    title = models.CharField(max_length=500)
    hn_id = models.CharField(max_length=50, unique=True)
    points = models.IntegerField(null=True)
    comment_count = models.IntegerField()
    comments_link = models.URLField()
    date = models.DateTimeField()
    date_scraped = models.DateTimeField(auto_now_add = True)
    date_modified = models.DateTimeField(auto_now = True)
    link = models.URLField(max_length=2000)
    posted_by = models.CharField(max_length=100, null=True)

So, since this is deployed and it's now in production. What if we wanted to add another field called tags that will store a string of tags, like so:

    tags = models.CharField(max_length=500)

This change isn't so easy to do. What you might do is figure out how the other CharFields are set in the database and run an ALTER TABLE query, like so:

ALTER TABLE posts_post
  ADD COLUMN tags varchar(500)

As you can see, writing these queries, managing them in the code repository, and ensuring they run in the right order can get quite involved and error prone.

Enter South

South is designed to allow you to do data, and schema migrations. That means that when you need to change the type of a field, length, or add/delete a field, you'd use South. Instead of running ALTER TABLE, with South, we'd simply run this manage command:

./manage.py schemamigration posts --auto
./manage.py migrate posts

The first command will generate the SQL that's needed to change your schema and then the second command will attempt to make the change in the database. For details on getting started with South, see the documentation.

grappelli

Documentation: http://django-grappelli.readthedocs.org/en/latest/

Grappelli takes the vanilla Django admin interface and gives it a nice and consistent look & feel. In addition it gives you inline sortables with drag & drop functionality, autocompletion, and a customizable dashboard.
Grappelli