django-registration

Published: August 13, 2015. Filed under: Django, Python.

I mentioned a couple weeks ago that lately I’ve been in the process of providing updated releases for all the various open-source projects I maintain, and specifically mentioned a desire to resurrect django-registration which, once upon a time, was the most popular thing I’d ever written. Over the past week I’ve been focusing more heavily on that, and now it’s time to start talking about a release.

Ancient history

I’ve always felt pretty strongly that Django’s killer feature is its concept of an application; the ability to wrap up a chunk of useful functionality in a reusable way, and then compose larger things out of those neatly-encapsulated bits of functionality, gives you a pretty big head start in many types of Web development projects. In fact, back in 2008, at the very first DjangoCon, I gave a talk along those lines, encouraging people to build reusable, extensible Django applications. And though some of the advice in that slide deck hasn’t aged well (like writing for Python 2.3 — hey, it was 2008! — or stuffing everything into keyword arguments in function-based views, now that we can do class-based views so easily), the basic philosophy still works.

At the time, django-registration was written not just to fill a need in the application ecosystem, but so I could have an example to point to of the reusable application philosophy done right (at least, for values of “right” that corresponded to my opinions). And django-registration itself was incredibly popular; I got into the habit of looking for telltale signs of it on Django-powered sites, and was eventually blown away by the number of places it seemed to be in use.

But the march of progress was not kind to django-registration. First of all, there was constant pressure to support all kinds of configurability in the application; there were arguments for supporting not just a custom registration form class or template name, but also all the other stuff Django’s (function-based) generic views supported, like passing in extra context variables. This led to the last real release of django-registration, 0.8 (there was a 1.0 later on, but it seems not to have been widely adopted, and was kind of a mess at the time anyway), which introduced class-based “backends” you could subclass to override various options.

And then Django’s authentication system became more complicated. The straw that broke the camel’s back, ultimately, was custom User models, which required various workarounds in django-registration to avoid just completely erroring out the moment the app was installed in a project using a custom User.

From the ashes

So django-registration more or less died for several years. I officially announced I was no longer maintaining it in 2013, and though some people have tried to pick up the final version and keep it up-to-date with modern Django releases, it mostly was superseded by newer solutions, especially things like django-allauth which also supported lots of social-media-login options.

But more recently I’ve come around to the view that there is still a niche for something resembling the original django-registration. Not everyone uses Facebook or GitHub authentication, and in fact a lot of people still just use the stock django.contrib.auth setup out-of-the-box (which isn’t a bad thing — Django’s default auth system is pretty darned good at covering the common cases people want for user authentication and management). So I made the decision to go back to django-registration, clean it up, get it working on modern (i.e., 1.7 and 1.8) versions of Django, and release it into the world again.

The result is the current state of the repository, which I’ve been hacking on for about a week now.

What’s new

First of all, let me be clear: this isn’t yet a final release. In fact, I’m not yet calling it a beta or even an alpha status. It isn’t installable from the Python Package Index, and though it does have a test suite that passes and provides 100% coverage, I can’t make any guarantees that it won’t eat your site, burn your house down and run outside to kick puppies.

That said, I’ve got a draft of updated documentation, and it includes a basic upgrade guide for people who (for whatever reason) still have an ancient 0.8-ish install rattling around.

Under the hood, the whole thing is now implemented cleanly using Django’s class-based generic views, which are what I wanted but didn’t have when writing 0.8’s backend system. There are two views — RegistrationView and ActivationView — for you to use, subclass and tinker with, and customization is done entirely through the standard mechanisms Django provides for its class-based views. You can pass quite a few things in the URLconf and they’ll just work, or you can subclass the views and override.

Support for custom User models is there, in the sense that the default registration workflows use get_user_model() and settings.AUTH_USER_MODEL where appropriate, instead of hard-coding references to django.contrib.auth.models.User. They do, however, still make some assumptions about the structure of your User model, so if you’re using something that departs significantly from Django’s stock User class you’ll need to do some subclassing and overriding to handle that.

And, of course, the code works and is tested on Django 1.7 and 1.8, on any of Python 2.7, 3.3 or 3.4.

The version number is something I’ve gone back and forth on; for a little while I had it marked as working toward 2.0, to signify that it was a break from the last widely-used release (even though that version wasn’t yet 1.0), but eventually settled on just having django-registrations version number track the latest release of Django it had been fully tested against. Since, at this point, that’s Django 1.8, the impending release of django-registration will also be numbered 1.8.

What’s next

At the moment, I’m labeling this as pre-alpha code for people to check out, poke at and offer feedback on. Assuming no show-stopping problems turn up in the next couple of weeks, I’ll probably just work on the documentation, do some style passes over the code, and gear up for a formal release sometime toward the end of August or the beginning of September. If you’d like to help out with that, feel free to grab the code from GitHub, try it out, and file issues and/or pull requests.