django-registration 3.0

django-registration is an 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, install django-registration, then read 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

The 3.0 release of django-registration supports Django 1.11, 2.0 and 2.1 on the following Python versions:

  • Django 1.11 supports Python 2.7, 3.4, 3.5 and 3.6.
  • Django 2.0 supports Python 3.4, 3.5, 3.6 and 3.7.
  • Django 2.1 supports Python 3.5, 3.6 and 3.7.

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 a supported version of Python, pip should have come bundled with your installation of Python.

Once you have pip, type:

pip install django-registration

If you don’t have a copy of a compatible version of Django, this will also automatically install one for you, and will install a third-party library required by some of django-registration’s validation code.

Warning

Python 2

If you are using Python 2, you should install the latest Django 1.11 release before installing django-registration. Later versions of Django no longer support Python 2, and installation will fail. To install a compatible version of Django for Python 2, run pip install “Django>=1.11,<2.0”.

Installing from a source checkout

If you want to work on django-registration, you can obtain a source checkout.

The development repository for django-registration is at <https://github.com/ubernostrum/django-registration>. If 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 git commands to check out the specific revision you want, and perform an “editable” install (allowing you to change code as you work on it) by typing:

pip install -e .

Next steps

To get up and running quickly, check out 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 two workflows built in to django-registration:

  • The two-step 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 one-step workflow, in which a user signs up and their account is immediately active and logged in.

The guide below covers use of these two workflows. Regardless of which one you choose to use, you should add “django_registration” to your INSTALLED_APPS setting.

Important

Django’s authentication system must be installed

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.

Note

Additional steps for account security

While django-registration does what it can to secure the user signup process, its scope is deliberately limited; please read the security documentation for recommendations on steps to secure user accounts beyond what django-registration alone can do.

Configuring the two-step activation workflow

The configuration process for using the two-step 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:

ACCOUNT_ACTIVATION_DAYS = 7 # One-week activation window

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. The URLconf for the two-step activation workflow can be found at django_registration.backends.activation.urls, and so can 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('django_registration.backends.activation.urls')),
    url(r'^accounts/', include('django.contrib.auth.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.

The sample URL configuration above also sets up the built-in auth views included in Django (login, logout, password reset, etc.) via the django.contrib.auth.urls URLconf.

The following URL names are defined by this URLconf:

  • django_registration_register is the account-registration view.
  • django_registration_complete is the post-registration success message.
  • django_registration_activate is the account-activation view.
  • django_registration_activation_complete is the post-activation success message.
  • django_registration_disallowed is a message indicating registration is not currently permitted.

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.

django_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.
django_registration/registration_complete.html

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

django_registration/activation_failed.html

Used if account activation fails. Has the following context:

activation_error
A dict containing the information supplied to the ActivationError which occurred during activation. See the documentation for that exception for a description of the keys, and the documentation for ActivationView for the specific values used in different failure situations.
django_registration/activation_complete.html

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

django_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.
request
The HttpRequest object representing the request in which the user registered.
scheme
The protocol scheme used during registration; will be either ‘http’ or ‘https’.
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.
user
The newly-created user object.
django_registration/activation_email_body.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.
request
The HttpRequest object representing the request in which the user registered.
scheme
The protocol scheme used during registration; will be either ‘http’ or ‘https’.
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.
user
The newly-created user object.

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 produces plain-text email, and so these templates should 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 one-step workflow

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

You will need to configure URLs to use the one-step workflow; the easiest way is to include() the URLconf django_registration.backends.one_step.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('django_registration.backends.one_step.urls')),
    url(r'^accounts/', include('django.contrib.auth.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 documentation above for details of this template’s context.

The two-step activation workflow

The two-step activation workflow, found in django_registration.backends.activation, implements a two-step registration process: a user signs up, an inactive account is created, and an email is sent containing an activation link which must be clicked to make the account active.

Behavior and configuration

A default URLconf is provided, which you can include() in your URL configuration; that URLconf is django_registration.backends.activation.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('django_registration.backends.activation.urls')),
    url(r'^accounts/', include('django.contrib.auth.urls')),
    # More URL patterns ...
]

That 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 use include() to include the URLconf django.contrib.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 django_registration.backends.activation.urls handles this for you.

This workflow makes use of up to three settings (click for details on each):

By default, this workflow uses 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 this 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 django_registration.backends.activation.views.RegistrationView

A subclass of django_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().

Parameters:form (django_registration.forms.RegistrationForm) – The registration form.
Return type:django.contrib.auth.models.AbstractUser
get_activation_key(user)

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

Parameters:user (django.contrib.auth.models.AbstractUser) – The new user account.
Return type:str
get_email_context(activation_key)

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

Parameters:activation_key (str) – The activation key for the new user account.
Return type:dict
send_activation_email(user)

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

Parameters:user (django.contrib.auth.models.AbstractUser) – The new user account.
Return type:None
email_body_template

A string specifying the template to use for the body of the activation email. Default is “django_registration/activation_email.txt”.

email_subject_template

A string specifying the template to use for the subject of the activation email. Default is “django_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 django_registration.backends.activation.views.ActivationView

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

Errors in activating the user account will raise ActivationError, with one of the following values for the exception’s code:

“already_activated”
Indicates the account has already been activated.
“bad_username”
Indicates the username decoded from the activation key is invalid (does not correspond to any user account).
“expired”
Indicates the account/activation key has expired.
“invalid_key”
Generic indicator that the activation key was invalid.

Important customization points unique to this class are:

get_user(username)

Given a username (determined by the activation key), looks up and returns the corresponding instance of the user model. If no such account exists, raises ActivationError as described above. In the base implementation, checks the is_active field to avoid re-activating already-active accounts, and raises ActivationError with code already_activated to indicate this case.

Parameters:username (str) – The username of the new user account.
Return type:django.contrib.auth.models.AbstractUser
Raises:django_registration.exceptions.ActivationError – if no matching inactive user account exists.
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. Raises ActivationError, as described above, if the activation key has an invalid signature or if the timestamp is too old.

Parameters:activation_key (str) – The activation key for the new user account.
Return type:str
Raises:django_registration.exceptions.ActivationError – if the activation key has an invalid signature or is expired.

How it works

When a user signs up, the activation 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 the username of the new account, signed using Django’s cryptographic signing tools (specifically, 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.

Security considerations

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

encoded_username:timestamp:signature

where encoded_username is the username of the new account, timestamp is the timestamp of the time the user registered, and signature is an HMAC of the username and timestamp. The username and HMAC will be URL-safe base64 encoded; the timestamp will be base62 encoded.

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 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 one-step workflow

As an alternative to the two-step (registration and activation) workflow, django-registration bundles a one-step registration workflow in django_registration.backends.one_step. This workflow consists of as few steps 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, include the URLconf django_registration.backends.one_step.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('django_registration.backends.one_step.urls')),
    url(r'^accounts/', include('django.contrib.auth.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 django_registration.backends.one_step.views.RegistrationView and overriding the method get_success_url() or setting the attribute success_url. You can also do this in a URLconf. For example:

from django.conf.urls import include, url

from django_registration.backends.one_step import RegistrationView

urlpatterns = [
    # Other URL patterns ...
    url(r'^accounts/register/',
        RegistrationView.as_view(success_url='/profile/'),
        name='django_registration_register'),
    url(r'^accounts/', include('django_registration.backends.one_step.urls')),
    url(r'^accounts/', include('django.contrib.auth.urls')),
    # More URL patterns ...
]

The default form class used for account registration will be django_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 django_registration.backends.one_step.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: django_registration/registration_form.html. See the quick start guide for details of this template’s context.

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 many types of registration workflows.

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 django_registration.views.RegistrationView

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

Standard attributes and methods of FormView can be overridden to control behavior as described in Django’s documentation, with the exception of get_success_url(), which must use the signature documented below.

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 RegistrationForm or a subclass of it).

This method should return the newly-registered user instance, and should send the signal django_registration.signals.user_registered. Note that this is not automatically done for you when writing your own custom subclass, so you must send this signal manually.

Parameters:form (django_registration.forms.RegistrationForm) – The registration form to use.
Return type:django.contrib.auth.models.AbstractUser

Useful optional places to override or customize on subclasses are:

disallowed_url

The URL to redirect to when registration is disallowed. Can be a hard-coded string, the string resulting from calling Django’s reverse() helper, or the lazy object produced by Django’s reverse_lazy() helper. Default value is the result of calling reverse_lazy() with the URL name ‘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 django_registration.forms.RegistrationForm.

success_url

The URL to redirect to after successful registration. Can be a hard-coded string, the string resulting from calling Django’s reverse() helper, or the lazy object produced by Django’s reverse_lazy() helper. Can be overridden on a per-request basis (see below). Default value is None; subclasses must override and provide this.

template_name

The template to use for user registration. Should be a string. Default value is ‘django_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.

Return type:django_registration.forms.RegistrationForm
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 value of the same type as success_url (see above).

Parameters:user (django.contrib.auth.models.AbstractUser) – The new user account.
Return type:str
registration_allowed()

Should indicate whether user registration is allowed, either in general or for this specific request. Default value is the value of the setting REGISTRATION_OPEN.

Return type:bool
class django_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 raise ActivationError (if activation was not successful).

Return type:django.contrib.auth.models.AbstractUser
Raises:django_registration.exceptions.ActivationError – if activation fails.

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

success_url

The URL to redirect to after successful activation. Can be a hard-coded string, the string resulting from calling Django’s reverse() helper, or the lazy object produced by Django’s reverse_lazy() helper. Can be overridden on a per-request basis (see below). Default value is None; subclasses must override and provide this.

template_name

The template to use after failed user activation. Should be a string. Default value is ‘django_registration/activation_failed.html’.

get_success_url(user)

Return a URL to redirect to after successful activation, on a per-request or per-user basis. If not overridden, will use success_url. Should return a value of the same type as success_url (see above).

Parameters:user (django.contrib.auth.models.AbstractUser) – The activated user account.
Return type:str

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 django_registration.forms.RegistrationForm

A 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.
email
The email address to use for the new account.
password1
The password to use for the new account.
password2
The password to use for the new account, repeated to catch typos.

Note

Validation of usernames

Django supplies a default regex-based validator for usernames in its base AbstractBaseUser implementation, allowing any word character along with the following set of additional characters: ., @, +, and -. However, in Django 1.11 on Python 2 this regex uses the re.ASCII flag, while on Python 3 it uses the re.UNICODE flag. This means that if you’re using Django 1.11, the set of accepted characters will vary depending on the Python version you use.

Because it’s a subclass of Django’s UserCreationForm, RegistrationForm will inherit the base validation defined by Django. It also applies one custom validator: ReservedNameValidator. See the documentation for ReservedNameValidator for notes on why it exists and how to customize its behavior.

class django_registration.forms.RegistrationFormCaseInsensitive

A subclass of RegistrationForm which enforces case-insensitive uniqueness of usernames, by applying CaseInsensitiveUnique to the username field.

Note

Unicode case handling

On all versions of Python, this form will normalize the username value to form NFKC, matching Django’s default approach to Unicode normalization. On Python 3, it will also case-fold the value (Python 3 provides a native casefold() method on strings).

The validator will then use a case-insensitive (iexact) lookup to determine if a user with the same username already exists; the results of this query may depend on the quality of your database’s Unicode implementation, and on configuration details. The results may also be surprising to developers who are primarily used to English/ASCII text, as Unicode’s case rules can be quite complex.

class django_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 django_registration.forms.RegistrationFormUniqueEmail

A subclass of RegistrationForm which enforces uniqueness of email addresses in addition to uniqueness of usernames, by applying CaseInsensitiveUnique to the email field.

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.

Older versions of django-registration did not generally support custom user models due to the additional complexity required. However, django-registration now can support custom user models. Depending on how significantly your custom user model differs from Django’s default, you may need to change only a few lines of code; custom user models significantly different from the default model may require more work to support.

Overview

The primary issue when using django-registration with a custom user model will be RegistrationForm. RegistrationForm is a subclass of Django’s built-in UserCreationForm. The only changes made by django-registration are:

Django’s UserCreationForm is a ModelForm with its model hard-coded to django.contrib.auth.models.User. As a result, you will always be required to supply a custom form class when using django-registration with a custom user model, if only to specify the correct model.

In the case where your user model is compatible with the default behavior of django-registration, (see below) you will be able to subclass RegistrationForm, set it to use your custom user model as the model, and then configure the views in django-registration to use your form subclass. For example, you might do the following (in a forms.py module somewhere in your codebase – do not directly edit django-registration’s code):

from django_registration.forms import RegistrationForm

from mycustomuserapp.models import MyCustomUser


class MyCustomUserForm(RegistrationForm):
    class Meta(RegistrationForm.Meta):
        model = MyCustomUser

You will also need to specify the fields to include in the form, via the fields declaration.

And then in your URL configuration (example here uses the two-step activation workflow):

from django.conf.urls import include, url

from django_registration.backends.activation.views import RegistrationView

from mycustomuserapp.forms import MyCustomUserForm


urlpatterns = [
    # ... other URL patterns here
    url(r'^accounts/register/$',
        RegistrationView.as_view(
            form_class=MyCustomUserForm
        ),
        name='django_registration_register',
    ),
    url(r'^accounts/',
        include('django_registration.backends.activation.urls')
    ),
    # ... more URL patterns
]

If your custom user model is not compatible with the built-in workflows of django-registration (see next section), you will probably need to subclass the provided views (either the base registration views, or the views of the workflow you want to use) and make the appropriate changes for your user model.

Determining compatibility of a custom user model

The built-in workflows and other code of django-registration do as much as is possible to ensure compatibility with custom user models: Django provides numerous facilities for retrieving and introspecting the user model without hard-coding a particular model class or field names, and django-registration makes use of them.

However, there are still some specific requirements you’ll want to be aware of.

The two-step activation workflow

The two-step activation requires that the following be true of your user model:

  • It must set the attribute USERNAME_FIELD to denote the field used as the username, and must define the method get_username() for retrieving the username value. Subclasses of Django’s AbstractBaseUser receive this attribute and method automatically.
  • It must have a field for storing an email address, and it must define the method get_email_field_name(), which will return the name of the email field. Subclasses of Django’s AbstractBaseUser receive this method automatically (and the backing attribute EmailField which normally stores the name of the email field). This field must be a textual field type (EmailField, CharField or TextField). Note that this field will be required by RegistrationForm, which is a difference from Django’s default UserCreationForm.
  • The username and email fields must be distinct. If you wish to use the email address as the username field, you will need to supply your own completely custom registration form.
  • It must have a field named is_active, and it must be a BooleanField indicating whether the user’s account is active.

If your custom user model defines additional fields beyond the minimum requirements, you’ll either need to ensure that all of those fields are optional (i.e., can be NULL in your database, or provide a suitable default value defined in the model), or you’ll need to specify the full list of fields to display in the fields section of the Meta declaration of your RegistrationForm subclass.

The one-step workflow

The one-step workflow places the following requirements on your user model:

  • It must set the attribute USERNAME_FIELD to denote the field used as the username, and must define the method get_username() for retrieving the username value. Subclasses of Django’s AbstractBaseUser receive this attribute and method automatically.
  • It must define a field named password for storing the user’s password (it will expect to find the value in the field password1 of the registration form).

Also note that RegistrationForm requires the email field, so either provide that field on your model or subclass RegistrationForm and override to remove the email field or make it optional.

If your custom user model defines additional fields beyond the minimum requirements, you’ll either need to ensure that all of those fields are optional (i.e., can be NULL in your database, or provide a suitable default value defined in the model), or you’ll need to specify the full list of fields to display in the fields section of the Meta declaration of your RegistrationForm subclass.

Because the one-step workflow logs in the new account immediately after creating it, you must either use Django’s ModelBackend as an authentication backend, or use an authentication backend which accepts a combination of USERNAME_FIELD and password as sufficient credentials.

Validation utilities

To ease the process of validating user registration data, django-registration includes some validation-related data and utilities.

Error messages

Several error messages are available as constants. All of them are marked for translation; most have translations already provided in django-registration.

django_registration.validators.DUPLICATE_EMAIL

Error message raised by RegistrationFormUniqueEmail when the supplied email address is not unique.

django_registration.validators.DUPLICATE_USERNAME

Error message raised by CaseInsensitiveValidator when the supplied username is not unique. This is the same string raised by Django’s default User model for a non-unique username.

django_registration.validators.RESERVED_NAME

Error message raised by ReservedNameValidator when it is given a value that is a reserved name.

django_registration.validators.TOS_REQUIRED

Error message raised by RegistrationFormTermsOfService when the terms-of-service field is not checked.

Rejecting “reserved” usernames

By default, django-registration treats some usernames as reserved.

Note

Why reserved names are reserved

Many Web applications enable per-user URLs (to display account information), and some may also create email addresses or even subdomains, based on a user’s username. While this is often useful, it also represents a risk: a user might register a name which conflicts with an important URL, email address or subdomain, and this might give that user control over it.

django-registration includes a list of reserved names, and rejects them as usernames by default, in order to avoid this issue.

class django_registration.validators.ReservedNameValidator(reserved_names)

A callable validator class (see Django’s validators documentation) which prohibits the use of a reserved name as the value.

By default, this validator is applied to the username field of django_registration.forms.RegistrationForm and all of its subclasses. This validator is attached to the list of validators for the username field, so to remove it (not recommended), subclass RegistrationForm and override __init__() to change the set of validators on the username field.

If you want to supply your own custom list of reserved names, you can subclass RegistrationForm and set the attribute reserved_names to the list of values you want to disallow.

The default list of reserved names, if you don’t specify one, is DEFAULT_RESERVED_NAMES. The validator will also reject any value beginning with the string “.well-known” (see RFC 5785).

Parameters:reserved_names (list) – A list of reserved names to forbid.
Raises:django.core.exceptions.ValidationError – if the provided value is reserved.

Several constants are provided which are used by this validator:

django_registration.validators.CA_ADDRESSES

A list of email usernames commonly used by certificate authorities when verifying identity.

django_registration.validators.NOREPLY_ADDRESSES

A list of common email usernames used for automated messages from a Web site (such as “noreply” and “mailer-daemon”).

django_registration.validators.PROTOCOL_HOSTNAMES

A list of protocol-specific hostnames sites commonly want to reserve, such as “www” and “mail”.

django_registration.validators.OTHER_SENSITIVE_NAMES

Other names, not covered by any of the other lists, which have the potential to conflict with common URLs or subdomains, such as “blog” and “docs”.

django_registration.validators.RFC_2142

A list of common email usernames specified by RFC 2142.

django_registration.validators.SENSITIVE_FILENAMES

A list of common filenames with important meanings, such that usernames should not be allowed to conflict with them (such as “favicon.ico” and “robots.txt”).

django_registration.validators.SPECIAL_HOSTNAMES

A list of hostnames with reserved or special meaning (such as “autoconfig”, used by some email clients to automatically discover configuration data for a domain).

django_registration.validators.DEFAULT_RESERVED_NAMES

A list made of the concatenation of all of the above lists, used as the default set of reserved names for ReservedNameValidator.

Protecting against homograph attacks

By default, Django permits a broad range of Unicode to be used in usernames; while this is useful for serving a worldwide audience, it also creates the possibility of homograph attacks through the use of characters which are easily visually confused for each other (for example: “pаypаl” containing a Cyrillic “а”, visually indistinguishable in many fonts from a Latin “а”).

To protect against this, django-registration applies some validation rules to usernames and email addresses.

django_registration.validators.validate_confusables(value)

A custom validator which prohibits the use of dangerously-confusable usernames.

This validator will reject any mixed-script value (as defined by Unicode ‘Script’ property) which also contains one or more characters that appear in the Unicode Visually Confusable Characters file.

This validator is enabled by default on the username field of registration forms.

Parameters:value (str) – The username value to validate (non-string usernames will not be checked)
Raises:django.core.exceptions.ValidationError – if the value is mixed-script confusable
django_registration.validators.validate_confusables_email(value)

A custom validator which prohibits the use of dangerously-confusable email address.

This validator will reject any email address where either the local-part of the domain is – when considered in isolation – dangerously confusable. A string is dangerously confusable if it is a mixed-script value (as defined by Unicode ‘Script’ property) which also contains one or more characters that appear in the Unicode Visually Confusable Characters file.

This validator is enabled by default on the email field of registration forms.

Parameters:value (str) – The email address to validate
Raises:django.core.exceptions.ValidationError – if the value is mixed-script confusable

Other validators

class django_registration.validators.CaseInsensitiveUnique(model, field_name)

A callable validator class (see Django’s validators documentation) which enforces case-insensitive uniqueness on a given field of a particular model. Used by RegistrationFormCaseInsensitive for case-insensitive username uniqueness, and RegistrationFormUniqueEmail for unique email addresses.

Parameters:
  • model (django.db.models.Model) – The model class to query against for uniqueness checks.
  • field_name (str) – The field name to perform the uniqueness check against.
Raises:

django.core.exceptions.ValidationError – if the value is not unique.

Exception classes

django-registration provides two base exception classes to signal errors which occur during the signup or activation processes.

exception django_registration.exceptions.RegistrationError(message, code, params)

Base exception class for all exceptions raised in django-registration. No code in django-registration will raise this exception directly; it serves solely to provide a distinguishing parent class for other errors. Arguments passed when the exception is raised will be stored and exposed as attributes of the same names on the exception object:

Parameters:
  • message (str) – A human-readable error message.
  • code (str) – A short but unique identifier used by subclasses to distinguish different error conditions.
  • params (dict) – Arbitrary key-value data to associate with the error.
exception django_registration.exceptions.ActivationError(message, code, params)

Exception class to indicate errors during account activation. Subclass of RegistrationError and inherits its attributes.

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.

Used by:

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 django_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 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; see the note about this salt value and security for details.

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.

django_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.

This signal is automatically sent for you by the base ActivationView, so unless you’ve overridden its get() method in a subclass you should not need to explicitly send it.

django_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.

This signal is not automatically sent for you by the base RegistrationView. It is sent by the subclasses implemented for the three included registration workflows, but if you write your own subclass of RegistrationView, you’ll need to send this signal as part of the implementation of the register() method.

Feature and API deprecation cycle

This document will list any features or APIs of django-registration which are deprecated and scheduled to be removed in future releases.

As of 3.0, no features or APIs are currently deprecated.

Security guide

Important

Reporting security issues

If you believe you have found a security issue in django-registration, please do not use the public GitHub issue tracker to report it. Instead, you can contact the author privately to report the issue.

Anything related to users or user accounts has security implications and represents a large source of potential security issues. This document is not an exhaustive guide to those implications and issues, and makes no guarantees that your particular use of Django or django-registration will be safe; instead, it provides a set of recommendations, and explanations for why django-registration does certain things or recommends particular approaches. Using this software responsibly is, ultimately, up to you.

Before continuing with this document, you should ensure that you’ve read and understood Django’s security documentation. Django provides a good overview of common security issues in the general field of web development, and an explanation of how it helps to protect against them or provides tools to help you do so.

You should also ensure you’re following Django’s security recommendations. You can check for many common issues by running:

python manage.py check --tag security

on your codebase.

Recommendation: use the two-step activation workflow

Two user-signup workflows are included in django-registration, along with support for writing your own. If you choose to use one of the included workflows, the two-step activation workflow is the recommended default.

The activation workflow provides a verification step – the user must click a link sent to the email address they used to register – which can serve as an impediment to automated account creation for malicious purposes.

The activation workflow generates an activation key which consists of the new account’s username and the timestamp of the signup, verified using Django’s cryptographic signing tools which in turn use the HMAC implementation from the Python standard library. Thus, django-registration is not inventing or building any new cryptography, but only using existing/vetted implementations in an approved and standard manner.

Additionally, the activation workflow takes steps to ensure that its use of HMAC does not act as an oracle. Several parts of Django use the signing tools, and third-party applications are free to use them as well, so django-registration makes use of the ability to supply a salt value for the purpose of “namespacing” HMAC usage. Thus an activation token generated by django-registration’s activation workflow should not be usable for attacks against other HMAC-carrying values generated by the same installation of Django.

Restrictions on user names: reserved names

By default, django-registration applies a list of reserved names, and does not permit users to create accounts using those names (see ReservedNameValidator). The default list of reserved names includes many names that could cause confusion or even inappropriate access. These reserved names fall into several categories:

  • Usernames which could allow a user to impersonate or be seen as a site administrator. For example, ‘admin’ or ‘administrator’.
  • Usernames corresponding to standard/protocol-specific email addresses (relevant for sites where creating an account also creates an email address with that username). For example, ‘webmaster’.
  • Usernames corresponding to standard/sensitive subdomain names (relevant for sites where creating an account also creates a subdomain corresponding to the username). For example, ‘ftp’ or ‘autodiscover’.
  • Usernames which correspond to sensitive URLs (relevant for sites where user profiles appear at a URL containing the username). For example, ‘contact’ or ‘buy’.

It is strongly recommended that you leave the reserved-name validation enabled.

Restrictions on user names and email addresses: Unicode

By default, django-registration permits the use of Unicode in usernames and email addresses. However, to prevent some types of Unicode-related attacks, django-registration will not permit certain specific uses of Unicode characters.

For example, while the username ‘admin’ cannot normally be registered (see above), a user might still attempt to register a name that appears visually identical, by substituting a Cyrillic ‘a’ or other similar-appearing character for the first character. This is a homograph attack.

To prevent homograph attacks, django-registration applies the following rule to usernames, and to the local-part and the domain of email addresses:

  • If the submitted value is mixed-script (contains characters from multiple different scripts, as in the above example which would mix Cyrillic and Latin characters), and
  • If the submitted value contains characters appearing in the Unicode Visually Confusable Characters file,
  • Then the value will be rejected.

See validate_confusables() and validate_confusables_email().

This should not interfere with legitimate use of Unicode, or of non-English/non-Latin characters in usernames and email addresses. To avoid a common false-positive situation, the local-part and domain of an email address are checked independently of each other.

It is strongly recommended that you leave this validation enabled.

Additional steps to secure user accounts

The scope of django-registration is solely the implementation of user-signup workflows, which limits the ways in which django-registration alone can protect your users. Other features of Django itself, or of other third-party applications, can provide significant increases in protection.

In particular, it is recommended that you:

  • Prevent the use of common passwords. You can catch some common passwords by enabling Django’s CommonPasswordValidator, which uses a list of twenty thousand common passwords. A more comprehensive option is the password validator and other utilities from pwned-passwords-django, which checks against a database containing (as of mid-2018) over half a billion passwords found in data breaches.
  • Use two-factor authentication via authenticator applications or hardware security keys (not SMS). The package django-two-factor provides integration for two-factor authentication into Django’s auth framework.

Upgrading from previous versions

The current release series of django-registration is the 3.x series, which is not backwards-compatible with the django-registration 2.x release series.

Changes between django-registration 2.x and 3.x

Module renaming

Prior to 3.x, django-registration installed a Python module named registration. To avoid silent incompatibilities, and to conform to more recent best practices, django-registration 3.x now installs a module named django_registration. Attempts to import from the registration module will immediately fail with ImportError.

Many installations will be able to adapt by replacing references to registration with references to django_registration.

Removal of model-based workflow

The two-step model-based signup workflow, which has been present since the first public release of django-registration in 2007, has now been removed. In its place, it is recommended that you use the two-step activation workflow instead, as that workflow requires no server-side storage of additional data beyond the user account itself.

Renaming of two-step activation workflow

The two-step activation workflow was previously found at registration.backends.hmac; it has been renamed and is now found at registration.backends.activation.

Renaming of one-step workflow

The one-step workflow was previously found at registration.backends.simple; it has been renamed and is now found at registration.backends.one_step.

Removal of auth URLs

Prior to 3.x, django-registration’s default URLconf modules for its built-in workflows would attempt to include the Django auth views (login, logout, password reset, etc.) for you. This became untenable with the rewrite of Django’s auth views to be class-based, as it required detecting the set of auth views and choosing a set of URL patterns at runtime.

As a result, auth views are no longer automatically configured for you; if you want them, include() the URLconf django.contrib.auth.urls at a location of your choosing.

Distinguishing activation failure conditions

Prior to 3.x, failures to activate a user account (in workflows which use activation) all simply returned None in place of the activated account. This meant it was not possible to determine, from inspecting the result, what exactly caused the failure.

In django-registration 3.x, activation failures raise an exception – ActivationError – with a message and code (such as “expired”), to indicate the cause of failure. This exception is caught by ActivationView and turned into the template context variable activation_error.

Changes to custom user support

Support for custom user models has been brought more in line with the features Django offers. This affects compatibility of custom user models with django-registration’s default forms and views. In particular, custom user models should now provide, in addition to USERNAME_FIELD, the get_username() and get_email_field_name() methods. See the custom user documentation for details.

Changes to success_url

Both the registration and activation views mimic Django’s own generic views in supporting a choice of ways to specify where to redirect after a successful registration or activation; you can either set the attribute success_url on the view class, or implement the method get_success_url() . However, there is a key difference between the base Django generic-view version of this, and the version in django-registration: when calling a get_success_url() method, django-registration passes the user account as an argument.

This is incompatible with the behavior of Django’s base FormMixin, which expects get_success_url() to take zero arguments.

Also, earlier versions of django-registration allowed success_url and get_success_url() to provide either a string URL, or a tuple of (viewname, args, kwargs) to pass to Django’s reverse() helper, in order to work around issues caused by calling reverse() at the level of a class attribute.

In django-registration 3.x, the user argument to get_success_url() is now optional, meaning FormMixin’s default behavior is now compatible with any get_success_url() implementation that doesn’t require the user object; as a result, implementations which don’t rely on the user object should either switch to specifying success_url as an attribute, or change their own signature to get_success_url(self, user=None).

Also, the ability to supply the 3-tuple of arguments for reverse() has been removed; both success_url and get_success_url() now must be/return either a string, or a lazy object that resolves to a string. To avoid class-level calls to reverse(), use django.urls.reverse_lazy() instead.

Removed “no free email” form

Earlier versions of django-registration included a form class, RegistrationFormNoFreeEmail, which attempted to forbid user signups using common free/throwaway email providers. Since this is a pointless task (the number of possible domains of such providers is ever-growing), this form class has been removed.

Template names

Since django-registration’s Python module has been renamed from registration to django_registration, its default template folder has also been renamed, from registration to django_registration. Additionally, the following templates have undergone name changes:

  • The default template name for the body of the activation email in the two-step activation workflow is now django_registration/activation_email_body.txt (previously, it was registration/activation_email.txt)
  • The default template name for ActivationView and its subclasses is now django_registration/activation_failed.html (previously, it was registration/activate.html).

Renaming of URL patterns

Prior to 3.x, django-registration’s included URLconf modules provided URL pattern names beginning with “registration”. For example: “registration_register”. In 3.x, these are all renamed to begin with “django_registration”. For example: “django_registration_register”.

Other changes

The URLconf registration.urls has been removed; it was an alias for the URLconf of the model-based workflow, which has also been removed.

The compatibility alias registration.backends.default, which also pointed to the model-based workflow, has been removed.

Changes during the 2.x release series

One major change occurred between django-registration 2.0 and 2.1: the addition in version 2.1 of the ReservedNameValidator, which is now used by default on RegistrationForm and its subclasses.

This is technically backwards-incompatible, since a set of usernames which previously could be registered now cannot be registered, but was included because the security benefits outweigh the edge cases of the now-disallowed usernames. If you need to allow users to register with usernames forbidden by this validator, see its documentation for notes on how to customize or disable it.

In 2.2, the behavior of the RegistrationProfile.expired() method was clarified to accommodate user expectations; it does not return (and thus, RegistrationProfile.delete_expired_users() does not delete) profiles of users who had successfully activated.

In django-registration 2.3, the new validators validate_confusables() and validate_confusables_email() were added, and are applied by default to the username field and email field, respectively, of registration forms. This may cause some usernames which previously were accepted to no longer be accepted, but like the reserved-name validator this change was made because its security benefits significantly outweigh the edge cases in which it might disallow an otherwise-acceptable username or email address. If for some reason you need to allow registration with usernames or email addresses containing potentially dangerous use of Unicode, you can subclass the registration form and remove these validators, though doing so is not recommended.

Versions prior to 2.0

A 1.0 release of django-registration existed, but the 2.x series was compatible with it.

Prior to 1.0, the most widely-adopted version of django-registration was 0.8; the changes from 0.8 to 2.x were large and significant, and if any installations on 0.8 still exist and wish to upgrade to more recent versions, it is likely the most effective route will be to discard all code using 0.8 and start over from scratch with a 3.x release.

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 integration with third-party authentication services 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 modifying 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 3.0, Django 1.11, 2.0 and 2.1 are supported, on Python 2.7, (Django 1.11 only), 3.4 (Django 1.11 and 2.0 only), 3.5, 3.6 and 3.7 (Django 2.0 and 2.1 only).

I found a bug or want to make an improvement!

Important

Reporting security issues

If you believe you have found a security issue in django-registration, please do not use the public GitHub issue tracker to report it. Instead, you can contact the author privately to report the issue.

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?

Over the decade-plus 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 3.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 workflow, 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.

For more details, see the security guide.

How do I run the tests?

django-registration’s tests are run using tox, but typical installation of django-registration (via pip install django-registration) will not install the tests.

To run the tests, download the source (.tar.gz) distribution of django-registration 3.0 from its page on the Python Package Index, unpack it (tar zxvf django-registration-|release|.tar.gz on most Unix-like operating systems), and in the unpacked directory run tox.

Note that you will need to have tox installed already (pip install tox), and to run the full test matrix you will need to have each supported version of Python available. To run only the tests for a specific Python version and Django version, you can invoke tox with the -e flag. For example, to run tests for Python 3.6 and Django 2.0: tox -e py36-django20.

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 ranges from 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

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 provides a URLconf for this, at django.contrib.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?

See the custom user documentation.

Tips and tricks

How do I close user signups?

If you haven’t modified the behavior of the registration_allowed() method in RegistrationView, you can use the setting REGISTRATION_OPEN to control this; when the setting is True, or isn’t supplied, user registration will be permitted. When the setting is False, user registration will not be permitted.

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

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

How do I manually activate a user?

In the two-step activation workflow, toggle the is_active field of the user in the admin.

How do I delete expired unactivated accounts?

Perform a query for those accounts, and call the delete() method of the resulting QuerySet. Since django-registration doesn’t know in advance what your definition of “expired” will be, it leaves this step to you.

How do I allow Unicode in usernames?

Use Python 3. Django’s username validation allows any word character plus some additional characters, but the definition of “word character” depends on the Python version in use. On Python 2, only ASCII will be permitted; on Python 3, usernames containing word characters matched by a regex with the re.UNICODE flag will be accepted.

How do I tell why an account’s activation failed?

If you’re using the two-step activation workflow, the template context will contain a variable activation_error containing the information passed when the ActivationError was raised. This will indicate what caused the failure.

See also