django-registration update

Published September 19, 2007. Filed under: Django, Meta.

For those of you who are using/following it, I’ve just pushed out django-registration 0.3. The basic workflow of the application is still the same:

  1. User signs up for account.
  2. User receives activation email.
  3. User clicks link in email to activate account.

But under the hood quite a few things have been rearranged to make the application cleaner and more extensible, and there have been a couple of backwards-incompatible changes for anyone using an older version. Here’s how it breaks down.

Backwards-incompatible changes

You’ll now need to create one extra template — registration/activation_email_subject.txt — in order to use the activation emails. I’d gotten a number of requests to make this more configurable, and the solution I finally settled on was to use a template for the subject. One caveat you need to be aware of: because this is going to end up in the Subject: header of an email, it must render to a single line (multi-line subjects don’t work), and this will be enforced by the application; if your template renders to multiple lines, they will be collapsed into a single line for use in the email subject.

Also, if you were relying on the tos field in RegistrationForm you’ll need to make a small change: that field has been removed, and the ability to choose a form for the registration process has been added. A new class, RegistrationFormTermsOfService, provides the same behavior as the original RegistrationForm, so you can switch to using that and keep on going.

Finally, the context passed to the template for the activation email’s body has been changed: instead of the current_site variable containing only the domain, the variable site is now available and holds the full current Site object.

Configurable form classes

As mentioned above, you can now choose a form to use for the registration process, by passing the keyword argument form_class to the register view; this defaults to RegistrationForm. The only real requirement is that your form class (and you must pass the class, not an instance of it) must have a save() method which accepts the optional keyword argument profile_callback and which returns a User object.

Since this is now configurable, I’ve added a few example subclasses of RegistrationForm which provide useful variations on the registration process:

Any of these, or any other form class (whether it subclasses RegistrationForm or not, though that’s the easy way to do things) which implements save() as described above will work with the register view. This is useful both for customized registration logic, and for offering different types of registration (by mapping different URL patterns, with different values for the form_class argument, to the register view) to different classes of visitors.

Configurable templates

Both the register and activate views now accept an optional keyword argument template_name, just like Django’s built-in generic views. The defaults are still registration/registration_form.html and registration/activate.html, respectively, but again this adds flexibility for additional customization and opens up the possiblity of displaying different registration systems to different people.

Easy maintenance

There’s been a method — RegistrationProfile.objects.delete_expired_users() — for cleaning out user accounts which were never registered, but it’s never been particularly easy to use it in any sort of automated way. With this release, a script suitable for running as a cron job — registration/bin/delete_expired_users.py — has been added which will take care of this, and it includes instructions on how to add the appropriate line to your crontab.

This is intended to serve as a substitute for the need to reset registration profiles or re-send activation emails: if a user doesn’t receive or doesn’t act on the initial email, their inactive account will be deleted once it expires and they can register again.

Documentation

The bundled documentation has also been significantly expanded; I’ve always been a stickler for giving everything a useful docstring, but the files in the docs/ directory have been greatly expanded and now provide reasonably good standalone documentation for the entire application.

Unicode updates

Since Django’s Unicode branch has been merged for a while, and things seem to be pretty stable, I’ve gone ahead and updated django-registration to work properly in a Unicode-aware Django. This means that RegistrationProfile now defines __unicode__() instead of __str__(), and that the Unicode-aware versions of various utility functions are now used throughout the app.

Internationalization

And the big one that quite a few people have been waiting for: all (I hope) of the relevant strings in django-registration have now been marked for translation, and a conf directory has been added to hold translations. I know more than a couple folks have been hounding me about this since I release the very first version, and now that the Unicode branch is in and the app is updated to deal with that, it’s time to start opening up to internationalization.

Updated September 21: Looks like I misread the i18n docs. I’ve moved this to “locale” as is apparently needed for app-level i18n. You might want to “svn up” or download a fresh copy of the package.

The future

I’ve done some light testing and everything seems to work, but I can’t make any guarantees and I’d like to remind anyone who’s updating that django-registration is still officially beta software; if you discover bugs, please report them and I’ll get them fixed as soon as possible. Going forward, my plan is to shake out any remaining bugs, hopefully collect a few translations and then roll a 1.0 release; at this point I think the API is stable, with just the right amount of room for customization and extension, so once the code is known to be good and the internationalization opportunities have been explored, I’ll be ready to commit to maintaining a stable, production version.