Gestión de usuarios con django-registration

En el post de hoy vamos a ver como podemos gestionar los usuarios de nuestro proyecto Django de forma muy profesional (registro, email de confirmación de registro, recuperación de contraseña, etc) pero sin grandes complicaciones, gracias al paquete django-registration, que nos proporciona vistas y mecanismos predefinidos para los casos de uso más habituales vinculados al registro de usuarios. Además, podemos encontrar varios templates ya creados compatibles con django-registration para las vistas que necesita.

Funcionalidades por defecto

Para hacernos una idea de la potencia de django-registration, vamos a detallar el flujo de registro de usuario que proporciona el paquete por defecto tras instalarlo en nuestro proyecto:

  1. El usuario se registra proporcionando nombre de usuario, email, y password

  2. A partir de dicha información, se crea un nuevo objeto User con el campo is_active a False. Además, se genera y almacena una clave de activación, y se envía un email al usuario conteniendo un enlace que hay que clickar para activar la cuenta

  3. Tras hacer click en el enlace, la nueva cuenta se activa (is_active se pone a True), y a partir de ese momento el usuario ya puede loguearse.

Entorno

Como es habitual, trabajaremos en un proyecto nuevo (mi_proyecto) sobre un entorno virtual (miEntorno). Si tienes dudas, consulta los posts de iniciación.

Instalación de django-registration

Ya en nuestro entorno y creado el proyecto, descargamos el paquete con pip:

(miEntorno)$ pip install django-registration

De paso, actualizamos nuestro archivo con los requerimientos (opcional):

(miEntorno)$ pip freeze > requirements_pip.txt

Configuración

Debemos añadir registration a nuestras aplicaciones instaladas, así como django.contrib.auth. También recomiendan añadir django.contrib.sites, aunque de momento no lo añadiremos.

También podemos especificar el tiempo que tiene un usuario para activar la cuenta a través del enlace recibido, mediante la variable ACCOUNT_ACTIVATION_DAYS.

Todo esto, lo incorporamos al módulo settings (mi_proyecto/mi_proyecto/settings.py):

INSTALLED_APPS = (
'django.contrib.admin',

'django.contrib.auth',
'registration',
)

ACCOUNT_ACTIVATION_DAYS
= 7

A continuación deberemos sincronizar la base de datos para crear las tablas necesarias para las aplicaciones instaladas:

(miEntorno)$ manage.py syncdb

Activamos las urls del backend por defecto

El default backend para el registro de usuarios incluye un URLconf con ciertas tipologías de URL vinculadas a las vistas que usará django-registration, por lo que tendremos que incluirlo en nuestro archivo mi_proyecto/mi_proyecto/urls.py, dejándolo como sigue:

from django.conf.urls import patterns, include, url

from django.contrib import admin
admin
.autodiscover()

urlpatterns
= patterns('',
(r'^accounts/', include('registration.backends.default.urls')),
url
(r'^admin/', include('admin.site.urls')),
)

Lo definimos con la ruta acounts/ pero podría ser cualquier otra que eligiéramos. Lo importante es que ahora los usuarios se podrán registrar visitando la URL /accounts/register/, loguear una vez activada su cuenta en /accounts/login/, hacer logout en /accounts/logout/, etc.

Descargamos los templates

Si buscamos en Google por django-registration-templates veremos que hay varios recursos que podemos usar. Nosotros, nos descargaremos los templates de https://github.com/macdhuibh/django-registration-templates (lo podemos descargar en ZIP).

Abrimos el ZIP y seleccionamos la carpeta registrations y el archivo base.html, que los copiaremos en nuestro proyecto, en el directorio mi_proyecto/static/templates, dejando la siguiente estructura:

mi_proyecto
    /db.sqlite3
    /manage.py
    /mi_proyecto
        /…
    /static
        /templates
            /registrations
                /…
            /base.html

Tendremos que añadir el directorio static y el de templates en el módulo settings (mi_proyecto/mi_proyecto/settings.py)

STATIC_URL = '/static/'

TEMPLATE_DIRS
= (
os
.path.join(os.path.dirname(os.path.dirname(__file__)), 'static', 'templates'),
)

Empecemos a usar los templates

Para evitar errores vamos al template base.html, y comentamos (con {# #}) la línea que hace referencia a una url inversa index que por ahora no tenemos:

{# <a href="{% url 'index' %}">{% trans "Home" %}</a> | #}

Hecho esto, ejecutamos el servidor

(miEntorno)$ ./manage.py runserver

y vamos a http://127.0.0.1:8000/accounts/login/

y deberíamos ver la siguiente pantalla:
django-registration template login

Por supuesto, os puede parecer que este template es muy básico, pero lo cierto es que si estamos usando bootstrap y ya tenemos un archivo base.html, con unos cambios mínimos como darle la clase que toca al botón, podemos tener una vista de login mucho más potente como podemos ver a continuación.

django bootstrap login template

En todo caso, independientemente del diseño, veremos que podemos loguearnos (con el usuario con el que generamos la base de datos) pero nos intentará llevar a la página profile y nos saltará un error ya que no tenemos ninguna vista ni url para la misma. Algo parecido nos pasará si intentamos resetear el password.

Por otro lado, si intentamos crear un usuario, se cargará bien la vista de registro, pero al darle al botón de aceptar nos saltará un error, ya que no hemos configurado la aplicación para el envío de e-mails.

Configurando el envío de emails

Para configurar el envío de e-mails a través de nuestro proyecto Django, deberemos especificar la información de nuestra cuenta de correo en el módulo settings (mi_proyecto/mi_proyecto/settings.py).

En este ejemplo vamos a mostrar la información que sería necesaria para configurar una cuenta de Gmail:

# Email related stuff
EMAIL_HOST
= 'smtp.gmail.com'
EMAIL_HOST_USER
= 'micorreo@gmail.com'
EMAIL_HOST_PASSWORD
= 'mipassword!!!!'
EMAIL_USE_TLS
= True

Solo con esto, ya podríamos registrar nuevos usuarios, y cada uno de ellos recibiría en su email el enlace para activar la cuenta en un correo similar a este:

Activate account at 127.0.0.1:8000:

http://127.0.0.1:8000/accounts/activate/1b7b76c29b9b14erfeeed2b8a579df8d2b5f7701/

Link is valid for 7 days.

Podremos comprobar que se ha creado el nuevo usuario desde el panel de administración (lo hemos definido en /admin/)

Vistas que requieren estar autentificado

Solo a nivel de recordatorio, comentar que podemos usar el decorador @login_required para decirle a una vista que solo se puede ejecutar si el usuario está logueado.

Además, desde los templates, tenemos la opción de evaluar si el usuario está logueado de la siguiente forma:

{% if request.user.is_authenticated %}
...do something...
{% endif %}

Y eso ha sido todo en cuanto a django-registration, como véis, una forma muy sencilla de incorporar la mecánica de registro a nuestro proyecto.

¡Saludos!