5 Django Packages that Get Too Little Love

Lots of packages get a lot of love like django-rest-framework and wagtail, and rightfully so, they’re awesome! But I wanted to give some less well know ones some love.


Sometimes your business users want to be able to run arbitrary SQL queries against a database for various reasons. You don’t want to give them direct database access; that’s crazy. Sandbox them here, and get a bunch of other features like the ability to download CSVs of the data, do sorting, and pivot tables.


Lots of stuff on the web is shown in tables. It’s really handy to be able to manipulate html tables with the same ease as you can manipulate html forms in Django. That’s what this does for you. Place data in columns, make the data sortable, and have pagination.

It’s easily extensible with django-filter to add in some searching and filtering. And it’s totally compatible with whatever frontend you might want — bootstrap, foundation, or roll your own.

import django_tables2 as tables
from .models import Address
class AddressTable(tables.Table):
user = tables.Column(accessor='address.user')
zip_code = tables.Column(verbose_name='Zip')
city = tables.Column(verbose_name='Town')

class Meta:
model = Address
order_by = '-zip_code'
fields = sequence = ('user', 'zip_code', 'city',)


Every once in a while you want some wiki-like functionality. django-wiki is meant to be an extensible base that you can make it into whatever you like. It’ll also work in place as a wiki by itself if you want. It supports markdown, version control, and decent out of the box UI.


By itself, django-reversion is already very awesome. However, adding in this package to compare them, you can do comparisons like below.


REST APIs are awesome, and django-rest-framework does an awesome job with that. But what if you wanted to emit events of receiving them. Then you need a webhook. Thus, you have this package which supports a very DRY approach for simply decorating your model in a similar way to django-rest-framework. Here’s a small taste from the docs:

### settings.py ###

# other apps here...

'book.added': 'bookstore.Book.created',
'book.changed': 'bookstore.Book.updated+',
'book.removed': 'bookstore.Book.deleted',
'book.read': 'bookstore.Book.read',
'user.logged_in': None

### bookstore/models.py ###

class Book(models.Model):
user = models.ForeignKey('auth.User')
title = models.CharField(max_length=128)
pages = models.PositiveIntegerField()
fiction = models.BooleanField()

def serialize_hook(self, hook):
return {
'hook': hook.dict(),
'data': {
'id': self.id,
'title': self.title,
'pages': self.pages,
'fiction': self.fiction,

def mark_as_read(self):
from rest_hooks.signals import hook_event
instance=self # the Book object
### USAGE ###
>>> from django.contrib.auth.models import User
>>> from rest_hooks.model import Hook
>>> jrrtolkien = User.objects.create(username='jrrtolkien')
>>> hook = Hook(user=jrrtolkien,
>>> hook.save() # creates the hook and stores it for later...
>>> from bookstore.models import Book
>>> book = Book(user=jrrtolkien,
title='The Two Towers',
>>> book.save() # fires off 'bookstore.Book.created' hook automatically