2011-04-09 24 views
12

Estoy compilando mi primera aplicación django. Tengo un usuario y el usuario tiene una lista de favoritos. Un usuario tiene exactamente una lista de favoritos, y esa lista pertenece exclusivamente a ese usuario.Crear una instancia de OneToOne en la creación del modelo

class User(models.Model): 
    name = models.CharField(max_length=200) 

class FavouriteList(models.Model): 
    user = models.OneToOneField(User) 
    favourites = models.ManyToManyField(Favourite, blank=True) 

Cuando se crea un nuevo usuario, que quiere asegurarse de que el usuario tiene un FavouriteList. He buscado en la documentación de Django y no he tenido mucha suerte.

¿Alguien sabe cómo puedo asegurarme de que un modelo tenga un objeto secundario (por ejemplo, FavouriteList) cuando se crea?

+0

Posible duplicado de [¿Puede Django crear automáticamente un modelo relacionado de uno a uno?] (Http://stackoverflow.com/questions/1652550/can-django-automatically-create-a-related-one-to- one-model) –

Respuesta

24

La forma más común de lograr esto es utilizar el sistema de señales de Django. Puede adjuntar un manejador de señal (solo una función en alguna parte) a la señal post_save para el modelo de Usuario, y crear su lista de favoritos dentro de esa devolución de llamada.

from django.db.models.signals import post_save 
from django.dispatch import receiver 
from django.contrib.auth.models import User 

@receiver(post_save, sender=User) 
def create_favorites(sender, instance, created, **kwargs): 
    if created: 
     Favorites.objects.create(user=instance) 

Lo anterior fue adaptado del Django signals docs. Asegúrese de leer los documentos de las señales por completo porque hay algunos problemas que pueden afectarlo, como dónde debe vivir el código de su manejador de señal y cómo evitar manipuladores duplicados.

+3

¡no solo el más común, es la forma * correcta * de hacerlo! – Agos

+0

actualizó los documentos de 1.3 a 1.11. los documentos 'dev' nunca estarían desactualizados, pero tal vez hubiera sido la mejor edición – TankorSmash

+0

Muchas gracias. :) –

2

Una forma sería la de registrar una señal de post_save con el siguiente controlador:

def user_save(sender, instance, created, **kwargs): 
    if created: 
    FavouriteList.objects.get_or_create(user=instance) 
7

Un excelente plugin django-annoying resuelve esto para usted con AutoOneToOneField. Lo estoy usando para perfiles de usuario en todos los proyectos de django en los que trabajo.

+0

Esto es muy bueno ... Parece que cada vez estoy saltando más en este aro. Gracias por el consejo. – nicorellius

Cuestiones relacionadas