El libro de Django 1.0

12.6. Grupos

Los grupos son una forma genérica de trabajar con varios usuarios a la vez, de forma que se les pueda asignar permisos o etiquetas en bloque. Un usuario puede pertenecer a varios grupos a la vez.

Un usuario que pertenezca a un grupo recibe automáticamente todos los permisos que se la hayan otorgado al grupo. Por ejemplo, si el grupo Editores tiene el permiso can_edit_home_page, cualquier usuario que pertenezca a dicho grupo también tiene ese permiso.

Los grupos también son una forma cómoda de categorizar a los usuarios para asignarles una determinada etiqueta, o para otorgarles una funcionalidad extra. Por ejemplo, se puede crear un grupo Usuarios especiales, y utilizar código para permitir el acceso a determinadas porciones de tu sitio sólo a los miembros de ese grupo, o para enviarles un correo electrónico sólo a ellos.

Al igual que con los usuarios, la manera más sencilla de gestionar los grupos es usando la interfaz de administración de Django. Los grupos, en cualquier caso, son modelos Django que residen en el módulo django.contrib.auth.models así que, al igual que en el caso anterior, puedes usar la API de acceso a la base de datos para trabajar con los grupos a bajo nivel.

12.6.1. Mensajes

El sistema de mensajes es un forma muy ligera y sencilla de enviarle mensajes a un usuario. Cada usuario tiene asociada una cola de mensajes, de forma que los mensajes lleguen en el orden en que fueron enviados. Los mensajes no tienen ni fecha de caducidad ni fecha de envío.

La interfaz de administración de Django usa los mensajes para notificar que determinadas acciones han podido ser llevadas a cabo con éxito. Por ejemplo, al crear un objeto, verás que aparece un mensaje en lo alto de la página de administración, indicando que se ha podido crear el objeto sin problemas.

Puedes usar la misma API para enviar o mostrar mensajes en tu propia aplicación. Las llamadas de la API son bastante simples:

  • Para crear un nuevo mensaje usa user.message_set.create(message='message_text').
  • Para recuperar/eliminar mensajes usa user.get_and_delete_messages(), la cual retorna una lista de objetos Message en la cola del usuario (si es que existiera alguno) y elimina el mensaje de la misma.

En el siguiente ejemplo, la vista guarda un mensaje para el usuario después de crear una lista de reproducción:

def create_playlist(request, songs):
    # Create the playlist with the given songs.
    # ...
    request.user.message_set.create(
        message="Your playlist was added successfully."
    )
    return render_to_response("playlists/create.html",
        context_instance=RequestContext(request))

Al usar RequestContext, los mensajes del usuario actual, si los tuviera, están accesibles desde la variable de contexto usando el nombre {{ messages }}. El siguiente ejemplo representa un fragmento de código que muestras los mensajes:

{% if messages %}
<ul>
    {% for message in messages %}
    <li>{{ message }}</li>
    {% endfor %}
</ul>
{% endif %}

Hay que hacer notar que RequestContext llama a get_and_delete_messages de forma implícita, por lo que los mensajes serán borrados, aún si no se muestran en pantalla.

Por último, el sistema de mensajería sólo funciona para usuarios de la base de datos. Para enviar mensajes a usuarios anónimos hay que usar en entorno de sesiones directamente.

12.6.2. Perfiles

La parte final de nuestro puzzle consiste en el sistema de perfiles. Para entender mejor que es este sistema y para que sirve, veamos primero el problema que se supone tiene que resolver.

El resumen sería este: Muchos sitios en Internet necesitan almacenar más información acerca de sus usuarios de la que está disponible en un objeto de la clase User. Para resolver este problema, otros entornos definen una serie de campos "extra". Django, por el contrario, ha optado por proporcionar un mecanismo sencillo que permita crear un perfil con los datos que queramos, y que queda enlazado con la cuenta de usuario. Estos perfiles pueden incluso ser diferentes según cada proyecto, y también se pueden gestionar diferentes perfiles para sitios diferentes usando la misma base de datos.

El primer paso para crear un perfil es definir el modelo que va a almacenar la información que queremos guardar. El único requerimiento que Django impone a este modelo es que disponga de una campo de tipo ForeignKey, que sea único (unique=True) y que lo vincule con el modelo User. Además, el campo debe llamarse user. Aparte de eso, puedes usar tantos y tan variados campos de datos como quieres. El siguiente ejemplo muestra un perfil absolutamente arbitrario:

from django.db import models
from django.contrib.auth.models import User

class MySiteProfile(models.Model):
    # This is the only required field
    user = models.ForeignKey(User, unique=True)

    # The rest is completely up to you...
    favorite_band = models.CharField(maxlength=100, blank=True)
    favorite_cheese = models.CharField(maxlength=100, blank=True)
    lucky_number = models.IntegerField()

El siguiente paso es decirle a Django donde buscar estos perfiles. Para ello asigna a la variable de configuración AUTH_PROFILE_MODULE el identificador de tu modelo. Así, si el perfil que definimos en el ejemplo anterior residiera en una aplicación llamada "myapp", pondrías esto en tu fichero de configuración:

AUTH_PROFILE_MODULE = "myapp.mysiteprofile"

Una vez hecho esto, se puede acceder al perfil del usuario llamando a user.get_profile(). Esta función elevará una excepción de tipo DoesNotExist si el usuario no tiene creado el perfil (puedes atrapar esta excepción y crear el perfil en ese momento).