Django es el entorno de desarrollo web para perfeccionistas con límites de tiempo

Métodos para crear perfiles de usuario

En múltiples ocasiones nos gustaría extender el modelo User para que incluyera otros campos y funciones. La manera "oficial" de hacer esto (la mostrada en la documentación de Django) es creando un modelo para el perfil de usuario que incluya un campo con una ForeignKey apuntando a la clase User. Vamos a ver cómo se puede hacer de la forma oficial, con herencia y utilizando un método alternativo añadiendo atributos a la clase User con add_to_class.

Método "oficial"

from django.contrib.auth.models import User

class Perfil(models.Model):
    user = models.ForeignKey(User, unique=True)
    direccion = models.CharField(max_length=250, blank=True)
    telefono = models.PositiveIntegerField(null=True, blank=True)

Utilizamos unique=True en el campo user para asegurarnos de que sólo pueda haber un único perfil por cada usuario. Luego añadimos AUTH_PROFILE_MODULE a nuestro archivo settings.py:

AUTH_PROFILE_MODULE = 'mi_aplicacion.Perfil'

A partir de ese momento podemos acceder al perfil del usuario con user.get_profile(). Esta es la forma "oficial" de hacerlo pero presenta desventajas: Algunos atributos del usuario se acceden como user.atributo y otros como user.get_profile().atributo. Y esto se complica más aún cuando tenemos que establecer relaciones entre usuarios: ¿Ponemos la relación entre perfiles? ¿Entre Perfil y User? Generalmente es recomendable que la relación sea entre perfiles:

from django.contrib.auth.models import User

class Perfil(models.Model):
    user = models.ForeignKey(User, unique=True)
    direccion = models.CharField(max_length=250, blank=True)
    telefono = models.PositiveIntegerField(null=True, blank=True)
    amigos = models.ManyToManyField('self', symmetrical=True,  blank=True)

Aún así resulta molesto tener que acceder a los amigos de un usuario de esta manera:

for perfil in user.get_profile().amigos:
    print perfil.user # mostrar el usuario

Nos gustaría que fuese tan sencillo como:

for usuario in user.amigos:
    print usuario

Método mediante herencia

Otra forma de hacerlo es creando una clase que herede de la clase User:

from django.contrib.auth.models import User

class Usuario(User):
    direccion = models.CharField(max_length=250, blank=True)
    telefono = models.PositiveIntegerField(null=True, blank=True)
    amigos = models.ManyToManyField('self', symmetrical=True,  blank=True)

De esta manera el problema se nos presenta al no poder acceder directamente a los datos del perfil con request.user en nuestras vistas.

Método usando add_to_class

Vamos a ver un método menos "limpio" que los anteriores pero más eficiente. Se trata de añadir atributos y métodos a la clase User antes de haber creado la tabla de usuario mediante el comando syncdb. En el models.py de cualquier aplicación del proyecto importamos la clase User y utilizamos add_to_class para añadir los atributos y las funciones que queramos a la clase User antes de crear su correspondiente tabla en la base de datos:

from django.contrib.auth.models import User

User.add_to_class('direccion', models.FloatField(null=True,blank=True))
User.add_to_class('telefono', models.PositiveIntegerField(null=True,blank=True))
User.add_to_class('amigos', models.ManyToManyField('self', symmetrical=True,  blank=True))

Ya podemos acceder a todos los atributos del usuario mediante user.atributo (p. ej: user.telefono). Crear un método propio para la clase User es igual de sencillo:

def es_popular(self):
    # devuelve True si tiene más de 100 amigos
    if self.amigos.all.count() > 100:
        return True
    else:
        return False

User.add_to_class('es_popular', es_popular)
# ahora podemos acceder al método mediante user.es_popular()

Ventajas de este método:

Se crea una única tabla para el usuario y su perfil: Esto es más eficiente si en las vistas vamos a necesitar información del usuario e información de su perfil constantemente. Con este método también podemos extender la clase User con métodos propios, y accedemos a todos los atributos del usuario mediante user.atributo.

Importante: Al crear un usuario deberás dar un valor siempre a los campos del perfil que no permitan valores nulos.

Publicado por Antonio Melé el Jueves 27 de Noviembre de 2008 Compártelo: Facebook: Twitter: | Categorías: auth, modelos, trucos

Entradas similares

Crear una imagen de nuestros modelos con django-command-extensions

Algo interesante que nos aporta django-command-extensions es poder crear una representación gráfica de nuestros modelos (o por decirlo de otro modo nuestro esquema de ...


Utilizar un formulario para modificar dos modelos

Actualización/Update: Zack translated this post into english and it is available here.

A veces tenemos que modificar información relativa a dos o más ...


 
Representar campos con choices en nuestras plantillas

Cuando usamos un campo con diferentes opciones (choices) en nuestro modelo utilizamos una lista de elementos cada uno con el valor real que se ...


Aplicar filtros a annotate() al usar Count()

A veces queremos utilizar la función de aggregación annotate() y aplicar filtros al modelo que se encuentra dentro de la misma, pero no es ...


 
 

0 comentarios:

No hay ningún comentario todavía.

Escribe un comentario: