Django invitation (strict version)
This is a fairly simple user-invitation application for Django, designed to make allowing user signups as painless as possible with quota restrictions: you need to be invited by someone else and the number of invitations is limited by user.
This application enables a common user-invitation workflow:
- User fills out an invitation form, entering an email address.
- An invitation key is created, and an invitation link is sent to the user's email address.
- User clicks the invitation link, the user is able to register in and begin contributing to your site.
Various methods of extending and customizing the invitation process are also provided.
In order to use django-invitation-strict, you will need to have a functioning installation of Django 1.4 or newer. django-invitation-strict has not been tested with older versions of Django.
The django-registration application is required in order to use django-invitation-strict. See ``Dependencies'' below.
Installing from a Mercurial checkout
If you have Mercurial installed on your computer, you can also obtain a complete copy of django-invitation-strict by typing:
hg clone https://bitbucket.org/antmar/django-invitation-strict
Inside the resulting "django-invitation-strict" directory will be a directory named "invitation", which is the actual Python module for this application; you can symlink it from somewhere on your Python path. Using a symlink offers easy upgrades: simply running hg pull -u inside the django-invitation-strict directory will fetch updates from the main repository and apply them to your local copy.
To use the invitation system with all its default settings, you'll need to do the following:
- Add invitation to the INSTALLED_APPS setting of your Django project.
- Set your django-invitation-strict settings in your settings file.
- INVITE_MODE - Boolean. Whether users are required to be invited before registering.
- INVITE_MODE_STRICT - Boolean. Whether users are required to register with the same address as the invitation was sent to.
- ACCOUNT_INVITATION_DAYS - Integer. The number of days invitation keys will remain valid after an invitation is sent.
- INVITATIONS_PER_USER - Integer. The number of invitations that are initially allotted to each newly registered user. -1 means infinite invitations.
Create the necessary templates (see the section on templates below for details).
Add this line to your site's root URLConf before registration urls:
- Run python manage.py syncdb to update your database with the django-invitation-strict models. If your project uses south for schema migrations, run python manage.py migrate instead.
- Link people to /accounts/invite/ so they can start inviting.
Templates used by django-invitation-strict
The views included in django-invitation-strict make use of five templates:
- invitation/invitation_form.html displays the invitation form for users to invite contacts.
- invitation/invitation_complete.html is displayed after the invitation email has been sent, to tell the user his contact has been emailed.
- invitation/invitation_email_subject.txt is used for the subject of the invitation email.
- invitation/invitation_email.txt is used for the body of the invitation email.
- invitation/invited.html displays the form where users can enter their invitation key and email address.
Examples of all of these templates are not provided; you will need to create them yourself.
Additionally, the URLConf provided with django-invitation-strict includes URL patterns for useful views in Django's built-in authentication application -- this means that a single include in your root URLConf can wire up invitation process.
How it works
Using the recommended default configuration, the URL /accounts/invite/ will map to the view invitation.views.invite, which displays an invitation form (an instance of invitation.forms.InvitationKeyForm); this form asks for an email address. It then does three things:
- Validates the form to be sure that's a valid email address.
- Creates an instance of invitation.models.InvitationKey, stores an activation key (a SHA1 hash generated from the new user's username plus a randomly-generated "salt").
- Sends an email to the user (at the address they supplied) containing a link which can be clicked to register a new account.
For details on customizing this process, including use of alternate invitation form classes, read the code (or django-registration documentation).
After the activation email has been sent, invitation.views.invite issues a redirect to the URL /accounts/invite/complete/. By default, this is mapped to the direct_to_template generic view, and displays the template invitation/invitation_complete.html; this is intended to show a short message telling the user his/her contact has been emailed.
The invitation link will map to the view invitation.views.invited, which will attempt to verify the activation key. If the activation key has expired (this is controlled by the setting ACCOUNT_INVITATION_DAYS, as described above), the register page will not be reachable (see the section on maintenance below for instructions on cleaning out expired keys which have not been used).
If the supplied invitation key is valid, the user will be redirected to the registration form. In strict mode the e-mail that they register with must match the address that the invitation was sent to. It is advisale to make the e-mail field in the registration form readonly. A special registration form is provided that enforces this: invitation.forms.StrictRegistrationForm which is based on registration.forms.RegistrationForm.
After registration, if the e-mail what the user registered with matches the e-mail that the registration was sent to, the user does not have to go through the 2-step registration process. Their account will be active immediately.
The INVITATIONS_PER_USER setting (integer) lets you decide the initial number of invitations left per user. Each new email sent consumes one invitation. (Administrators can use the Django Admin interface to modify the number of invitations a user has.)
Inevitably, a site which uses a two-step process for user invitation -- invitation followed by acceptation -- will accumulate a certain number of keys which were created but never used. These keys clutter up the database, so it's desirable to clean them out periodically. For this purpose, a Django command, cleanupinvitation, is provided, which is suitable for use as a regular cron job.
This application is built on top of django-registration. For now you need to install a special version of django-registration which is available at: https://bitbucket.org/antmar/django-registration
If you spot a bug
This wiki page is based on David Larlet's original documentation for django-invitation: