django-registration 2.0

django-registration is a simple, extensible application providing user registration functionality for Django-powered Web sites.

Although nearly all aspects of the registration process are customizable, out-of-the-box support is provided for two common use cases:

  • Two-phase registration, consisting of initial signup followed by a confirmation email with instructions for activating the new account.
  • One-phase registration, where a user signs up and is immediately active and logged in.

To get up and running quickly, consult the quick start guide, which describes the steps necessary to configure django-registration for the built-in workflows. For more detailed information, including how to customize the registration process (and support for alternate registration systems), read through the documentation listed below.

Installation guide

Before installing django-registration, you’ll need to have a copy of Django already installed. For information on obtaining and installing Django, consult the Django download page, which offers convenient packaged downloads and installation instructions.

The 2.0 release of django-registration supports Django 1.7, 1.8 and 1.9, on any Python version supported by those versions of Django:

  • Django 1.7 supports Python 2.7, 3.2, 3.3 and 3.4.
  • Django 1.8 suports Python 2.7, 3.2, 3.3, 3.4 and 3.5.
  • Django 1.9 supports Python 2.7, 3.4 and 3.5.

Important

Python 3.2

Although Django 1.7 and 1.8 support Python 3.2, and django-registration 2.0 supports it, many Python libraries supporting Python 3 impose a minimum requirement of Python 3.3 (due to conveniences added in Python 3.3 which make supporting Python 2 and 3 in the same codebase much simpler).

As a result, use of Python 3.2 is discouraged; Django 1.9 has already dropped support for it, and a future release of django-registration will likely drop Python 3.2 support as well.

Normal installation

The preferred method of installing django-registration is via pip, the standard Python package-installation tool. If you don’t have pip, instructions are available for how to obtain and install it. If you’re using Python 2.7.9 or later (for Python 2) or Python 3.4 or later (for Python 3), pip came bundled with your installation of Python.

Once you have pip, simply type:

pip install django-registration

Manual installation

It’s also possible to install django-registration manually. To do so, obtain the latest packaged version from the listing on the Python Package Index. Unpack the .tar.gz file, and run:

python setup.py install

Once you’ve installed django-registration, you can verify successful installation by opening a Python interpreter and typing import registration.

If the installation was successful, you’ll simply get a fresh Python prompt. If you instead see an ImportError, check the configuration of your install tools and your Python import path to ensure django-registration installed into a location Python can import from.

Installing from a source checkout

The development repository for django-registration is at <https://github.com/ubernostrum/django-registration>. Presuming you have git installed, you can obtain a copy of the repository by typing:

git clone https://github.com/ubernostrum/django-registration.git

From there, you can use normal git commands to check out the specific revision you want, and install it using python setup.py install.

Next steps

To get up and running quickly, checkout the quick start guide. For full documentation, see the documentation index.

Quick start guide

First you’ll need to have Django and django-registration installed; for details on that, see the installation guide.

The next steps will depend on which registration workflow you’d like to use. There are three workflows built in to django-registration; one is included largely for backwards compatibility with older releases, while the other two are recommended for new installations. Those two are:

  • The HMAC activation workflow, which implements a two-step process: a user signs up, then is emailed an activation link and must click it to activate the account.
  • The simple one-step workflow, in which a user simply signs up and their account is immediately active and logged in.

The guide below covers use of these two workflows.

Before proceeding with either of the recommended built-in workflows, you’ll need to ensure django.contrib.auth has been installed (by adding it to INSTALLED_APPS and running manage.py migrate to install needed database tables). Also, if you’re making use of a custom user model, you’ll probably want to pause and read the custom user compatibility guide before using django-registration.

Configuring the HMAC activation workflow

The configuration process for using the HMAC activation workflow is straightforward: you’ll need to specify a couple of settings, connect some URLs and create a few templates.

Required settings

Begin by adding the following setting to your Django settings file:

ACCOUNT_ACTIVATION_DAYS
This is the number of days users will have to activate their accounts after registering. If a user does not activate within that period, the account will remain permanently inactive unless a site administrator manually activates it.

For example, you might have something like the following in your Django settings file:

ACCOUNT_ACTIVATION_DAYS = 7 # One-week activation window; you may, of course, use a different value.

You’ll also need to have django.contrib.auth in your INSTALLED_APPS setting, since all of the registration workflows in django-registration make use of it.

Warning

You should not add registration to your INSTALLED_APPS setting if you’re following this document. This section is walking you through setup of the the HMAC activation workflow, and that does not make use of any custom models or other features which require registration to be in INSTALLED_APPS. Only add registration to your INSTALLED_APPS setting if you’re using the model-based activation workflow, or something derived from it.

Setting up URLs

Each bundled registration workflow in django-registration includes a Django URLconf which sets up URL patterns for the views in django-registration, as well as several useful views in django.contrib.auth (e.g., login, logout, password change/reset). The URLconf for the HMAC activation workflow can be found at registration.backends.hmac.urls, and so can simply be included in your project’s root URL configuration. For example, to place the URLs under the prefix /accounts/, you could add the following to your project’s root URLconf:

from django.conf.urls import include, url

urlpatterns = [
    # Other URL patterns ...
    url(r'^accounts/', include('registration.backends.hmac.urls')),
    # More URL patterns ...
]

Users would then be able to register by visiting the URL /accounts/register/, log in (once activated) at /accounts/login/, etc.

Another URLConf is also provided – at registration.auth_urls – which just handles the Django auth views, should you want to put those at a different location.

Required templates

You will also need to create several templates required by django-registration, and possibly additional templates required by views in django.contrib.auth. The templates required by django-registration are as follows; note that, with the exception of the templates used for account activation emails, all of these are rendered using a RequestContext and so will also receive any additional variables provided by context processors.

registration/registration_form.html

Used to show the form users will fill out to register. By default, has the following context:

form
The registration form. This will likely be a subclass of RegistrationForm; consult Django’s forms documentation for information on how to display this in a template.

registration/registration_complete.html

Used after successful completion of the registration form. This template has no context variables of its own, and should simply inform the user that an email containing account-activation information has been sent.

registration/activate.html

Used if account activation fails. With the default setup, has the following context:

activation_key
The activation key used during the activation attempt.

registration/activation_complete.html

Used after successful account activation. This template has no context variables of its own, and should simply inform the user that their account is now active.

registration/activation_email_subject.txt

Used to generate the subject line of the activation email. Because the subject line of an email must be a single line of text, any output from this template will be forcibly condensed to a single line before being used. This template has the following context:

activation_key
The activation key for the new account.
expiration_days
The number of days remaining during which the account may be activated.
site
An object representing the site on which the user registered; depending on whether django.contrib.sites is installed, this may be an instance of either django.contrib.sites.models.Site (if the sites application is installed) or django.contrib.sites.requests.RequestSite (if not). Consult the documentation for the Django sites framework for details regarding these objects’ interfaces.

registration/activation_email.txt

Used to generate the body of the activation email. Should display a link the user can click to activate the account. This template has the following context:

activation_key
The activation key for the new account.
expiration_days
The number of days remaining during which the account may be activated.
site
An object representing the site on which the user registered; depending on whether django.contrib.sites is installed, this may be an instance of either django.contrib.sites.models.Site (if the sites application is installed) or django.contrib.sites.requests.RequestSite (if not). Consult the documentation for the Django sites framework for details regarding these objects.

Note that the templates used to generate the account activation email use the extension .txt, not .html. Due to widespread antipathy toward and interoperability problems with HTML email, django-registration defaults to plain-text email, and so these templates should simply output plain text rather than HTML.

To make use of the views from django.contrib.auth (which are set up for you by the default URLconf mentioned above), you will also need to create the templates required by those views. Consult the documentation for Django’s authentication system for details regarding these templates.

Configuring the the simple one-step workflow

Also included is a simpler, one-step registration workflow, where a user signs up and their account is immediately active and logged in.

The simple workflow does not require any models other than those provided by Django’s own authentication system, so only django.contrib.auth needs to be in your INSTALLED_APPS setting.

You will need to configure URLs to use the simple workflow; the easiest way is to simply include() the URLconf registration.backends.simple.urls in your root URLconf. For example, to place the URLs under the prefix /accounts/ in your URL structure:

from django.conf.urls import include, url

urlpatterns = [
    # Other URL patterns ...
    url(r'^accounts/', include('registration.simple.hmac.urls')),
    # More URL patterns ...
]

Users could then register accounts by visiting the URL /accounts/register/.

This URLconf will also configure the appropriate URLs for the rest of the built-in django.contrib.auth views (log in, log out, password reset, etc.).

Finally, you will need to create one template: registration/registration_form.html. See the list of templates above for details of this template’s context.

The HMAC activation workflow

The HMAC workflow, found in registration.backends.hmac, implements a two-step registration process (signup, followed by activation), but unlike the older model-based activation workflow uses no models and does not store its activation key; instead, the activation key sent to the user is a timestamped, HMAC-verified value.

Unless you need to maintain compatibility in an existing install of django-registration which used the model-based workflow, it’s recommended you use the HMAC activation workflow for two-step signup processes.

Behavior and configuration

Since this workflow does not make use of any additional models beyond the user model (either Django’s default django.contrib.auth.models.User, or a custom user model), do not add registration to your INSTALLED_APPS setting.

You will need to configure URLs, however. A default URLconf is provided, which you can include() in your URL configuration; that URLconf is registration.backends.hmac.urls. For example, to place user registration under the URL prefix /accounts/, you could place the following in your root URLconf:

from django.conf.urls import include, url

urlpatterns = [
    # Other URL patterns ...
    url(r'^accounts/', include('registration.backends.hmac.urls')),
    # More URL patterns ...
]

That URLconf also sets up the views from django.contrib.auth (login, logout, password reset, etc.), though if you want those views at a different location, you can include() the URLconf registration.auth_urls to place only the django.contrib.auth views at a specific location in your URL hierarchy.

Note

URL patterns for activation

Although the actual value used in the activation key is the new user account’s username, the URL pattern for ActivationView does not need to match all possible legal characters in a username. The activation key that will be sent to the user (and thus matched in the URL) is produced by django.core.signing.dumps(), which base64-encodes its output. Thus, the only characters this pattern needs to match are those from the URL-safe base64 alphabet, plus the colon (“:”) which is used as a separator.

The default URL pattern for the activation view in registration.backends.hmac.urls handles this for you.

This workflow makes use of up to three settings:

By default, this workflow uses registration.forms.RegistrationForm as its form class for user registration; this can be overridden by passing the keyword argument form_class to the registration view.

Views

Two views are provided to implement the signup/activation process. These subclass the base views of django-registration, so anything that can be overridden/customized there can equally be overridden/customized here. There are some additional customization points specific to the HMAC implementation, which are listed below.

For an overview of the templates used by these views (other than those specified below), and their context variables, see the quick start guide.

class registration.backends.hmac.views.RegistrationView

A subclass of registration.views.RegistrationView implementing the signup portion of this workflow.

Important customization points unique to this class are:

create_inactive_user(form)

Creates and returns an inactive user account, and calls send_activation_email() to send the email with the activation key. The argument form is a valid registration form instance passed from register().

get_activation_key(user)

Given an instance of the user model, generates and returns an activation key (a string) for that user account.

get_email_context(activation_key)

Returns a dictionary of values to be used as template context when generating the activation email.

send_activation_email(user)

Given an inactive user account, generates and sends the activation email for that account.

email_body_template

A string specifying the template to use for the body of the activation email. Default is "registration/activation_email.txt".

email_subject_template

A string specifying the template to use for the subject of the activation email. Default is "registration/activation_email_subject.txt". Note that, to avoid header-injection vulnerabilities, the result of rendering this template will be forced into a single line of text, stripping newline characters.

class registration.backends.hmac.views.ActivationView

A subclass of registration.views.ActivationView implementing the activation portion of this workflow.

Important customization points unique to this class are:

get_user(username)

Given a username (determined by the activation key), look up and return the corresponding instance of the user model. Returns None if no such instance exists. In the base implementation, will include is_active=False in the query to avoid re-activation of already-active accounts.

validate_key(activation_key)

Given the activation key, verifies that it carries a valid signature and a timestamp no older than the number of days specified in the setting ACCOUNT_ACTIVATION_DAYS, and returns the username from the activation key. Returns None if the activation key has an invalid signature or if the timestamp is too old.

How it works

When a user signs up, the HMAC workflow creates a new User instance to represent the account, and sets the is_active field to False. It then sends an email to the address provided during signup, containing a link to activate the account. When the user clicks the link, the activation view sets is_active to True, after which the user can log in.

The activation key is simply the username of the new account, signed using Django’s cryptographic signing tools (specifically, signing.dumps() is used, to produce a guaranteed-URL-safe value). The activation process includes verification of the signature prior to activation, as well as verifying that the user is activating within the permitted window (as specified in the setting ACCOUNT_ACTIVATION_DAYS, mentioned above), through use of Django’s TimestampSigner.

Comparison to the model-activation workflow

The primary advantage of the HMAC activation workflow is that it requires no persistent storage of the activation key. However, this means there is no longer an automated way to differentiate accounts which have been purposefully deactivated (for example, as a way to ban a user) from accounts which failed to activate within a specified window. Additionally, it is possible a user could, if manually deactivated, re-activate their account if still within the activation window; for this reason, when using the is_active field to “ban” a user, it is best to also set the user’s password to an unusable value (i.e., by calling set_unusable_password() for that user). Calling set_unusable_password() will also make it easier to query for manually-deactivated users, as their passwords will (when using Django’s default User implementation) begin with the exclamation mark (!) character.

Since the HMAC activation workflow does not use any models, it also does not make use of the admin interface and thus does not offer a convenient way to re-send an activation email. Users who have difficulty receiving the activation email can simply be manually activated by a site administrator.

However, the reduced overhead of not needing to store the activation key makes this generally preferable to the model-based workflow.

Security considerations

The activation key emailed to the user in the HMAC activation workflow is a value obtained by using Django’s cryptographic signing tools.

In particular, the activation key is of the form:

encoded_username:timestamp:signature

Where encoded_username is the username of the new account, (URL-safe) base64-encoded, timestamp is a base62-encoded timestamp of the time the user registered, and signature is a (URL-safe) base64-encoded HMAC of the username and timestamp.

Django’s implementation uses the value of the SECRET_KEY setting as the key for HMAC; additionally, it permits the specification of a salt value which can be used to “namespace” different uses of HMAC across a Django-powered site.

The HMAC activation workflow will use the value (a string) of the setting REGISTRATION_SALT as the salt, defaulting to the string "registration" if that setting is not specified. This value does not need to be kept secret (only SECRET_KEY does); it serves only to ensure that other parts of a site which also produce signed values from user input could not be used as a way to generate activation keys for arbitrary usernames (and vice-versa).

The simple one-step workflow

As an alternative to the HMAC and model-based two-step (registration and activation) workflows, django-registration bundles a one-step registration workflow in registration.backends.simple. This workflow is deliberately as simple as possible:

  1. A user signs up by filling out a registration form.
  2. The user’s account is created and is active immediately, with no intermediate confirmation or activation step.
  3. The new user is logged in immediately.

Configuration

To use this workflow, simply include the URLconf registration.backends.simple.urls somewhere in your site’s own URL configuration. For example:

from django.conf.urls import include, url

urlpatterns = [
    # Other URL patterns ...
    url(r'^accounts/', include('registration.backends.simple.urls')),
    # More URL patterns ...
]

To control whether registration of new accounts is allowed, you can specify the setting REGISTRATION_OPEN.

Upon successful registration, the user will be redirected to the site’s home page – the URL /. This can be changed by subclassing registration.backends.simple.views.RegistrationView and overriding the method get_success_url().

The default form class used for account registration will be registration.forms.RegistrationForm, although this can be overridden by supplying a custom URL pattern for the registration view and passing the keyword argument form_class, or by subclassing registration.backends.simple.views.RegistrationView and either overriding form_class or implementing get_form_class(), and specifying the custom subclass in your URL patterns.

Templates

The one-step workflow uses only one custom template:

registration/registration_form.html

Used to show the form users will fill out to register. By default, has the following context:

form
The registration form. This will likely be a subclass of RegistrationForm; consult Django’s forms documentation for information on how to display this in a template.

The model-based activation workflow

This workflow implements a two-step – registration, followed by activation – process for user signup.

Note

Use of the model-based workflow is discouraged

The model-based activation workflow was originally the only workflow built in to django-registration, and later was the default one. However, it no longer represents the best practice for registration with modern versions of Django, and so it continues to be included only for backwards compatibility with existing installations of django-registration.

If you’re setting up a new installation and want a two-step process with activation, it’s recommended you use the HMAC activation workflow instead.

Also, note that this workflow was previously found in registration.backends.default, and imports from that location still function in django-registration 2.0 but now raise deprecation warnings. The correct location going forward is registration.backends.model_activation.

Default behavior and configuration

To make use of this workflow, simply add registration to your INSTALLED_APPS, run manage.py migrate to install its model, and include the URLconf registration.backends.model_activation.urls at whatever location you choose in your URL hierarchy. For example:

from django.conf.urls import include, url

urlpatterns = [
    # Other URL patterns ...
    url(r'^accounts/', include('registration.backends.model_activation.urls')),
    # More URL patterns ...
]

This workflow makes use of the following settings:

By default, this workflow uses registration.forms.RegistrationForm as its form class for user registration; this can be overridden by passing the keyword argument form_class to the registration view.

Two views are provided: registration.backends.model_activation.views.RegistrationView and registration.backends.model_activation.views.ActivationView. These views subclass django-registration‘s base RegistrationView and ActivationView, respectively, and implement the two-step registration/activation process.

Upon successful registration – not activation – the user will be redirected to the URL pattern named registration_complete.

Upon successful activation, the user will be redirected to the URL pattern named registration_activation_complete.

This workflow uses the same templates and contexts as the HMAC activation workflow, which is covered in the quick-start guide. Refer to the quick-start guide for documentation on those templates and their contexts.

How account data is stored for activation

During registration, a new instance of the user model (by default, Django’s django.contrib.auth.models.User – see the custom user documentation for notes on using a different model) is created to represent the new account, with the is_active field set to False. An email is then sent to the email address of the account, containing a link the user must click to activate the account; at that point the is_active field is set to True, and the user may log in normally.

Activation is handled by generating and storing an activation key in the database, using the following model:

class registration.models.RegistrationProfile

A simple representation of the information needed to activate a new user account. This is not a user profile; it simply provides a place to temporarily store the activation key and determine whether a given account has been activated.

Has the following fields:

user

A OneToOneField to the user model, representing the user account for which activation information is being stored.

activation_key

A 40-character CharField, storing the activation key for the account. Initially, the activation key is the hex digest of a SHA1 hash; after activation, this is reset to ACTIVATED.

Additionally, one class attribute exists:

ACTIVATED

A constant string used as the value of activation_key for accounts which have been activated.

And the following methods:

activation_key_expired()

Determines whether this account’s activation key has expired, and returns a boolean (True if expired, False otherwise). Uses the following algorithm:

  1. If activation_key is ACTIVATED, the account has already been activated and so the key is considered to have expired.
  2. Otherwise, the date of registration (obtained from the date_joined field of user) is compared to the current date; if the span between them is greater than the value of the setting ACCOUNT_ACTIVATION_DAYS, the key is considered to have expired.
Return type:bool
send_activation_email(site)

Sends an activation email to the address of the account.

The activation email will make use of two templates: registration/activation_email_subject.txt and registration/activation_email.txt, which are used for the subject of the email and the body of the email, respectively. Each will receive the following context:

activation_key
The value of activation_key.
expiration_days
The number of days the user has to activate, taken from the setting ACCOUNT_ACTIVATION_DAYS.
site
An object representing the site on which the account was registered; depending on whether django.contrib.sites is installed, this may be an instance of either django.contrib.sites.models.Site (if the sites application is installed) or django.contrib.sites.models.RequestSite (if not). Consult the documentation for the Django sites framework for details regarding these objects’ interfaces.

Note that, to avoid header-injection vulnerabilities, the rendered output of registration/activation_email_subject.txt will be forcibly condensed to a single line.

Parameters:site (django.contrib.sites.models.Site or django.contrib.sites.models.RequestSite) – An object representing the site on which account was registered.
Return type:None

Additionally, RegistrationProfile has a custom manager (accessed as RegistrationProfile.objects):

class registration.models.RegistrationManager

This manager provides several convenience methods for creating and working with instances of RegistrationProfile:

activate_user(activation_key)

Validates activation_key and, if valid, activates the associated account by setting its is_active field to True. To prevent re-activation of accounts, the activation_key of the RegistrationProfile for the account will be set to RegistrationProfile.ACTIVATED after successful activation.

Returns the user instance representing the account if activation is successful, False otherwise.

Parameters:activation_key (string, a 40-character SHA1 hexdigest) – The activation key to use for the activation.
Return type:user or bool
delete_expired_users()

Removes expired instances of RegistrationProfile, and their associated user accounts, from the database. This is useful as a periodic maintenance task to clean out accounts which registered but never activated.

Accounts to be deleted are identified by searching for instances of RegistrationProfile with expired activation keys and with associated user accounts which are inactive (have their is_active field set to False). To disable a user account without having it deleted, simply delete its associated RegistrationProfile; any User which does not have an associated RegistrationProfile will not be deleted.

A custom management command is provided which will execute this method, suitable for use in cron jobs or other scheduled maintenance tasks: manage.py cleanupregistration.

Return type:None
create_inactive_user(username, email, password, site[, send_email])

Creates a new, inactive user account and an associated instance of RegistrationProfile, sends the activation email and returns the new User object representing the account.

Parameters:
  • username (string) – The username to use for the new account.
  • email (string) – The email address to use for the new account.
  • password (string) – The password to use for the new account.
  • site (django.contrib.sites.models.Site or django.contrib.sites.models.RequestSite) – An object representing the site on which the account is being registered.
  • send_email (bool) – If True, the activation email will be sent to the account (by calling RegistrationProfile.send_activation_email()). If False, no email will be sent (but the account will still be inactive).
Return type:

user

create_profile(user)

Creates and returns a RegistrationProfile instance for the account represented by user.

The RegistrationProfile created by this method will have its activation_key set to a SHA1 hash generated from a combination of the account’s username and a random salt.

Parameters:user (User) – The user account; an instance of django.contrib.auth.models.User.
Return type:RegistrationProfile

Base view classes

In order to allow the utmost flexibility in customizing and supporting different workflows, django-registration makes use of Django’s support for class-based views. Included in django-registration are two base classes which can be subclassed to implement whatever workflow is required.

The built-in workflows in django-registration provide their own subclasses of these views, and the documentation for those workflows will indicate customization points specific to those subclasses. The following reference covers useful attributes and methods of the base classes, for use in writing your own custom subclasses.

class registration.views.RegistrationView

A subclass of Django’s FormView, which provides the infrastructure for supporting user registration.

Since it’s a subclass of FormView, RegistrationView has all the usual attributes and methods you can override.

When writing your own subclass, one method is required:

register(form)

Implement your registration logic here. form will be the (already-validated) form filled out by the user during the registration process (i.e., a valid instance of registration.forms.RegistrationForm or a subclass of it).

This method should return the newly-registered user instance, and should send the signal registration.signals.user_registered.

Useful optional places to override or customize on a RegistrationView subclass are:

disallowed_url

The URL to redirect to when registration is disallowed. Should be a string name of a URL pattern. Default value is "registration_disallowed".

form_class

The form class to use for user registration. Can be overridden on a per-request basis (see below). Should be the actual class object; by default, this class is registration.forms.RegistrationForm.

success_url

The URL to redirect to after successful registration. A string containing a (relative) URL, or a string name of a URL pattern, or a 3-tuple of arguments suitable for passing to Django’s redirect shortcut. Can be overridden on a per-request basis (see below). Default value is None, so that per-request customization is used instead.

template_name

The template to use for user registration. Should be a string. Default value is registration/registration_form.html.

get_form_class()

Select a form class to use on a per-request basis. If not overridden, will use form_class. Should be the actual class object.

get_success_url(user)

Return a URL to redirect to after successful registration, on a per-request or per-user basis. If not overridden, will use success_url. Should return a string containing a (relative) URL, or a string name of a URL pattern, or a 3-tuple of arguments suitable for passing to Django’s redirect shortcut.

registration_allowed()

Should return a boolean indicating whether user registration is allowed, either in general or for this specific request.

class registration.views.ActivationView

A subclass of Django’s TemplateView which provides support for a separate account-activation step, in workflows which require that.

One method is required:

activate(*args, **kwargs)

Implement your activation logic here. You are free to configure your URL patterns to pass any set of positional or keyword arguments to ActivationView, and they will in turn be passed to this method.

This method should return the newly-activated user instance (if activation was successful), or boolean False if activation was not successful.

Useful places to override or customize on an ActivationView subclass are:

template_name

The template to use for user activation. Should be a string. Default value is registration/activate.html.

get_success_url(user)

Return a URL to redirect to after successful registration, on a per-request or per-user basis. If not overridden, will use success_url. Should return a string containing a (relative) URL, or a string name of a URL pattern, or a 3-tuple of arguments suitable for passing to Django’s redirect shortcut.

Base form classes

Several form classes are provided with django-registration, covering common cases for gathering account information and implementing common constraints for user registration. These forms were designed with django-registration‘s built-in registration workflows in mind, but may also be useful in other situations.

class registration.forms.RegistrationForm

A simple form for registering an account. This is a subclass of Django’s built-in UserCreationForm, and has the following fields, all of which are required:

username
The username to use for the new account. This is represented as a text input which validates that the username is unique, consists entirely of alphanumeric characters and underscores and is at most 30 characters in length.
email
The email address to use for the new account. This is represented as a text input which accepts email addresses up to 75 characters in length.
password1
The password to use for the new account. This is represented as a password input (input type="password" in the rendered HTML).
password2
The password to use for the new account. This is represented as a password input (input type="password" in the rendered HTML).

Because this is a subclass of Django’s own UserCreationForm, the constraints on usernames and email addresses match those enforced by Django’s default authentication backend for instances of django.contrib.auth.models.User. The repeated entry of the password serves to catch typos.

The validation error for mismatched passwords is attached to the password2 field. This is a backwards-incompatible change from django-registration 1.0.

class registration.forms.RegistrationFormTermsOfService

A subclass of RegistrationForm which adds one additional, required field:

tos
A checkbox indicating agreement to the site’s terms of service/user agreement.
class registration.forms.RegistrationFormUniqueEmail

A subclass of RegistrationForm which enforces uniqueness of email addresses in addition to uniqueness of usernames.

class registration.forms.RegistrationFormNoFreeEmail

A subclass of RegistrationForm which disallows registration using addresses from some common free email providers. This can, in some cases, cut down on automated registration by spambots.

By default, the following domains are disallowed for email addresses:

  • aim.com
  • aol.com
  • email.com
  • gmail.com
  • googlemail.com
  • hotmail.com
  • hushmail.com
  • msn.com
  • mail.ru
  • mailinator.com
  • live.com
  • yahoo.com

To change this, subclass this form and set the class attribute bad_domains to a list of domains you wish to disallow.

Custom user models

When django-registration was first developed, Django’s authentication system supported only its own built-in user model, django.contrib.auth.models.User. More recent versions of Django have introduced support for custom user models.

It is possible to use django-registration with a custom user model, so long as certain factors are accounted for.

Warning

Using email address as username

If your custom user model treats the email address as a username, or otherwise does not have distinct email address and username fields, you must write a custom registration workflow including custom registration form; the built-in workflows of django-registration will not function with a user model which uses the email address as a username.

Writing a custom registration workflow

The most straightforward way to guarantee compatibility with a custom user model is simply to write your own custom registration workflow, subclassing RegistrationView, ActivationView, and RegistrationForm as necessary. Refer to the documentation for those classes for notes on how to customize them.

Using the built-in workflows

If you want to use one of the registration workflows built in to django-registration, there is some accommodation for custom user models. The two-step model workflow uses a model with a OneToOneField to the user model, and uses the recommended practice of referring to it via the AUTH_USER_MODEL setting. All built-in workflows also avoid importing or directly referring to Django’s default user model, instead using the get_user_model() helper provided in django.contrib.auth to obtain a reference to whatever model has been specified to represent users.

However, all of these workflows do make some assumptions about the structure of your user model.

The two-step workflows (both model-based and HMAC-based) require that your user model define the following fields, which are found on Django’s default user model:

  • email – a CharField or EmailField holding the user’s email address.
  • password – a CharField holding the user’s password.
  • is_active – a BooleanField indicating whether the user’s account is active.

You also must specify the attribute USERNAME_FIELD on your custom user model to denote the field used as the username, and that field must accept string values.

Additionally, the model-based workflow requires this field:

  • date_joined – a DateField or DateTimeField indicating when the user joined the site.

The model-based and HMAC workflows also require that the user model define a manager class named objects, and that this manager class provide a method create_user, which will create and return a user instance from the arguments USERNAME_FIELD (django-registration will use that to determine the name of the username field) email, and password, and require that the user model provide the email_user method on instances.

The simple one-step workflow requires USERNAME_FIELD to be specified (and for that field to accept strings), requires email and password fields, and requires the existence of an objects manager defining create_user, as in the two-step workflows.

If your custom user model cannot meet these API requirements, your only option for using django-registration will be to write your own registration workflow.

If you wish to write your own subclasses of the forms and views from the model-based workflow, but will be customizing them to an incompatible custom user model, also note that you must not add registration to your INSTALLED_APPS setting, as doing so would install the default workflow’s RegistrationProfile model, which does make the above-noted assumptions about the structure of your user model.

Custom settings

Although the choice of registration workflow does not necessarily require changes to your Django settings (as registration workflows are selected by including the appropriate URL patterns in your root URLconf), the built-in workflows of django-registration make use of several custom settings.

django.conf.settings.ACCOUNT_ACTIVATION_DAYS

An int indicating how long (in days) after signup an account has in which to activate.

This setting is required if using one of the built-in two-step workflows:

django.conf.settings.REGISTRATION_OPEN

A bool indicating whether registration of new accounts is currently permitted.

A default of True is assumed when this setting is not supplied, so specifying it is optional unless you want to temporarily close registration (in which case, set it to False).

Used by:

Third-party workflows wishing to use an alternate method of determining whether registration is allowed should subclass registration.views.RegistrationView (or a subclass of it from an existing workflow) and override registration_allowed().

django.conf.settings.REGISTRATION_SALT

A str used as an additional “salt” in the process of generating HMAC-signed activation keys.

This setting is optional, and a default of "registration" will be used if not specified. The value of this setting does not need to be kept secret; it is used solely as a way of namespacing HMAC usage.

Used by:

Signals used by django-registration

Much of django-registration‘s customizability comes through the ability to write and use different workflows for user registration. However, there are many cases where only a small bit of additional logic needs to be injected into the registration process, and writing a custom workflow to support this represents an unnecessary amount of work. A more lightweight customization option is provided through two custom signals which the built-in registration workflows send, and custom workflows are encouraged to send, at specific points during the registration process; functions listening for these signals can then add whatever logic is needed.

For general documentation on signals and the Django dispatcher, consult Django’s signals documentation. This documentation assumes that you are familiar with how signals work and the process of writing and connecting functions which will listen for signals.

registration.signals.user_activated

Sent when a user account is activated (not applicable to all workflows). Provides the following arguments:

sender
The ActivationView subclass used to activate the user.
user
A user-model instance representing the activated account.
request
The HttpRequest in which the account was activated.
registration.signals.user_registered

Sent when a new user account is registered. Provides the following arguments:

sender
The RegistrationView subclass used to register the account.
user
A user-model instance representing the new account.
request
The HttpRequest in which the new account was registered.

Upgrading from previous versions

Prior to 2.0, the last widely-deployed release of django-registration was 0.8; a 1.0 release was published, and 2.0 is mostly backwards-compatible with it, but 1.0 appears not to have seen wide adoption. As such, this guide covers the process of upgrading from django-registration 0.8, as well as from 1.0.

Backends are now class-based views

In django-registration 0.8, a registration workflow was implemented as a class with specific methods for the various steps of the registration process. In django-registration 2.0, a registration workflow is implemented as one or more class-based views.

In general, the required changes to implement a 0.8 registration workflow in django-registration 2.0 is:

0.8 backend class implementation 2.0 view subclass implementation
Backend class implementing register() registration.views.RegistrationView.register()
Backend class implementing activate() registration.views.ActivationView.activate()
Backend class implementing registration_allowed() registration.views.RegistrationView.registration_allowed()
Backend class implementing get_form_class() registration.views.RegistrationView.get_form_class()
Backend class implementing post_registration_redirect() registration.views.RegistrationView.get_success_url()
Backend class implementing post_activation_redirect() registration.views.ActivationView.get_success_url()

URLconf changes

If you were using one of the provided workflows in django-registration 0.8 without modification, you will not need to make any changes; both registration.backends.default.urls and registration.backends.simple.urls have been updated in django-registration 2.0 to correctly point to the new class-based views:

0.8 URLconf view reference 2.0 URLconf view reference
registration.views.register registration.views.RegistrationView.as_view()
registration.views.activate registration.views.ActivationView.as_view()

However, if you were using the two-step model-activation workflow, you should begin referring to registration.backends.model_activation.urls instead of registration.backends.default.urls or registration.urls, as the latter two are deprecated and support for them will be removed in a future release.

If you were passing custom arguments to the built-in registration views, those arguments should continue to work, so long as your URLconf is updated to refer to the new class-based views. For details of how to pass custom arguments to class-based views, see the Django class-based view documentation.

Template changes

When using RegistrationForm, the error from mismatched passwords now is attached to the password2 field rather than being a form-level error. To check for and display this error, you will need to change to accessing it via the password2 field rather than via non_field_errors() or the __all__ key in the errors dictionary.

Changes since 1.0

If you used django-registration 1.0, or a pre-release checkout of the 2.0 code, you will need to make some minor adjustments.

If you previously used registration.backends.default, you will now see deprecation warnings, as the former “default” workflow is now found in registration.backends.model_activation. Use of registration.backends.default continues to work in django-registration 2.0, but will be removed in the future.

Similarly, references to registration.urls should become references to registration.backends.model_activation.urls, and registration.urls is deprecated and will be removed in a future release.

If you had written custom subclasses of RegistrationView or of RegistrationView subclasses in the built-in workflows, the following changes need to be noted:

  • The register method now receives the RegistrationForm instance used during signup, rather than keyword arguments corresponding to the form’s cleaned_data.
  • RegistrationForm itself is now a subclass of Django’s built-in UserCreationForm, and as such is now a ModelForm subclass. This can cause metaclass conflict errors if you write a class which is a subclass of both RegistrationForm and a non-ModelForm form class; to avoid this, ensure that subclasses of RegistrationForm and/or ModelForm come first in your subclass’ method resolution order.
  • As noted above, the password-mismatch error message is now attached to the password2 field rather than being a form-level error.

Frequently-asked questions

The following are miscellaneous common questions and answers related to installing/using django-registration, culled from bug reports, emails and other sources.

General

How can I support social-media and other auth schemes, like Facebook or GitHub?

By using django-allauth. No single application can or should provide a universal API for every authentication system ever developed; django-registration sticks to making it easy to implement typical signup workflows using Django’s own user model and auth system (with some ability to use custom user models), while apps like django-allauth handle the vagaries of social authentication far more effectively.

What license is django-registration under?

django-registration is offered under a three-clause BSD-style license; this is an OSI-approved open-source license, and allows you a large degree of freedom in modifiying and redistributing the code. For the full terms, see the file LICENSE which came with your copy of django-registration; if you did not receive a copy of this file, you can view it online at <https://github.com/ubernostrum/django-registration/blob/master/LICENSE>.

What versions of Django and Python are supported?

As of django-registration 2.0, Django 1.7, 1.8 and 1.9 are supported, on Python 2.7, 3.2, 3.3, 3.4 or 3.5 (though note that Django 1.9 drops support for Python 3.2 and 3.3, and many libraries which support Python 3 do not support Python 3.2).

I found a bug or want to make an improvement!

The canonical development repository for django-registration is online at <https://github.com/ubernostrum/django-registration>. Issues and pull requests can both be filed there.

If you’d like to contribute to django-registration, that’s great! Just please remember that pull requests should include tests and documentation for any changes made, and that following PEP 8 is mandatory. Pull requests without documentation won’t be merged, and PEP 8 style violations or test coverage below 100% are both configured to break the build.

How secure is django-registration?

In the eight-year history of django-registration, there have been no security issues reported which required new releases to remedy. This doesn’t mean, though, that django-registration is perfectly secure: much will depend on ensuring best practices in deployment and server configuration, and there could always be security issues that just haven’t been recognized yet.

django-registration does, however, try to avoid common security issues:

  • django-registration 2.0 only supports versions of Django which were receiving upstream security support at the time of release.
  • django-registration does not attempt to generate or store passwords, and does not transmit credentials which could be used to log in (the only “credential” ever sent out by django-registration is an activation key used in the two-step activation workflows, and that key can only be used to make an account active; it cannot be used to log in).
  • django-registration works with Django’s own security features (including cryptographic features) where possible, rather than reinventing its own.

How do I run the tests?

django-registration makes use of Django’s own built-in unit-testing tools, and supports several ways to execute its test suite:

  • Within a Django project, simply invoke manage.py test registration.
  • If you’ve installed django-registration (so that it’s on your Python import path) and Django, but don’t yet have a project created or want to test independently of a project, you can run registration/runtests.py, or you can invoke python setup.py test (which will simply run registration/runtests.py).

Additionally, the setup.cfg file included in django-registration provides configuration for coverage.py, enabling easy recording and reporting of test coverage.

Installation and setup

How do I install django-registration?

Full instructions are available in the installation guide. For configuration, see the quick start guide.

Does django-registration come with any sample templates I can use right away?

No, for two reasons:

  1. Providing default templates with an application is generally hard to impossible, because different sites can have such wildly different design and template structure. Any attempt to provide templates which would work with all the possibilities would probably end up working with none of them.
  2. A number of things in django-registration depend on the specific registration workflow you use, including the variables which end up in template contexts. Since django-registration has no way of knowing in advance what workflow you’re going to be using, it also has no way of knowing what your templates will need to look like.

Fortunately, however, django-registration has good documentation which explains what context variables will be available to templates, and so it should be easy for anyone who knows Django’s template system to create templates which integrate with their own site.

Configuration

Should I used the model-based or HMAC activation workflow?

You’re free to choose whichever one you think best fits your needs. However, the model-based workflow is mostly provided for backwards compatibility with older versions of django-registration; it dates to 2007, and though it is still as functional as ever, the HMAC workflow has less overhead (i.e., no need to install or work with any models) due to being able to take advantage of more modern features in Django.

Do I need to rewrite the views to change the way they behave?

Not always. Any behavior controlled by an attribute on a class-based view can be changed by passing a different value for that attribute in the URLConf. See Django’s class-based view documentation for examples of this.

For more complex or fine-grained control, you will likely want to subclass RegistrationView or ActivationView, or both, add your custom logic to your subclasses, and then create a URLConf which makes use of your subclasses.

I don’t want to write my own URLconf because I don’t want to write patterns for all the auth views!

You’re in luck, then; django-registration provides a URLconf which only contains the patterns for the auth views, and which you can include in your own URLconf anywhere you’d like; it lives at registration.auth_urls.

I don’t like the names you’ve given to the URL patterns!

In that case, you should feel free to set up your own URLconf which uses the names you want.

I’m using a custom user model; how do I make that work?

Tips and tricks

How do I log a user in immediately after registration or activation?

Take a look at the implementation of the simple one-step workflow, which logs a user in immediately after registration.

How do I re-send an activation email?

Assuming you’re using the model-based workflow, a custom admin action is provided for this; in the admin for the RegistrationProfile model, simply click the checkbox for the user(s) you’d like to re-send the email for, then select the “Re-send activation emails” action.

How do I manually activate a user?

In the model-based workflow, a custom admin action is provided for this. In the admin for the RegistrationProfile model, click the checkbox for the user(s) you’d like to activate, then select the “Activate users” action.

In the HMAC-based workflow, simply toggle the is_active field of the user in the admin.

See also