users tutorial sent register create and django django-registration

django - tutorial - Crear un perfil de usuario extendido



email verification django (6)

Cuando llamas a profile.setUser() , creo que quieres pasar la instance lugar del sender como parámetro.

De la documentación de la señal registrada por el usuario , el sender refiere a la clase de User ; instance es el objeto de usuario real que se registró.

Tengo un modelo de perfil de usuario extendido en django:

class UserProfile(models.Model): user = models.ForeignKey(User, unique=True) #other things in that profile

Y un signals.py:

from registration.signals import user_registered from models import UserProfile from django.contrib.auth.models import User def createUserProfile(sender, instance, **kwargs): profile = users.models.UserProfile() profile.setUser(sender) profile.save() user_registered.connect(createUserProfile, sender=User)

Me aseguro de que la señal se registre teniendo esto en mi __init__.py :

import signals

Entonces, ¿eso debería crearme un nuevo perfil de usuario para cada usuario que se registre, verdad? Pero no es así Siempre obtengo errores de "La coincidencia de perfil de usuario no existe" cuando intento iniciar sesión, lo que significa que la entrada de la base de datos no está allí.

Debo decir que uso django-registration, que proporciona la señal user_registered.

La estructura de las aplicaciones importantes para esto es que tengo una aplicación llamada "usuarios", allí tengo: models.py, signals.py, urls.py y views.py (y algunas otras cosas que no deberían importar aquí ) La clase UserProfile se define en models.py.

Actualización : cambié el signal.py a:

from django.db.models.signals import post_save from models import UserProfile from django.contrib.auth.models import User def create_profile(sender, **kw): user = kw["instance"] if kw["created"]: profile = UserProfile() profile.user = user profile.save() post_save.connect(create_profile, sender=User)

Pero ahora obtengo un "IntegrityError":

"column user_id no es único"

Editar 2:

Lo encontré. Parece que de alguna manera registré la señal dos veces. La solución para esto se describe aquí: http://code.djangoproject.com/wiki/Signals#Helppost_saveseemstobeemittedtwiceforeachsave

Tuve que agregar un dispatch_uid, ahora mi signal.py se ve así y está funcionando:

from django.db.models.signals import post_save from django.contrib.auth.models import User from models import UserProfile from django.db import models def create_profile(sender, **kw): user = kw["instance"] if kw["created"]: profile = UserProfile(user=user) profile.save() post_save.connect(create_profile, sender=User, dispatch_uid="users-profilecreation-signal")


De acuerdo con mi última investigación, crear un archivo separado, por ejemplo, singals.py, no funciona.

Será mejor que conecte ''create_profile'' a ''post_save'' en su models.py directamente, de lo contrario, este fragmento de código no se ejecutará ya que está en un archivo separado y nadie lo importa.

Mi código final para su referencia:

# models.py # Here goes the definition of class UserProfile. class UserProfile(models.Model): ... # Use signal to automatically create user profile on user creation. # Another implementation: # def create_user_profile(sender, **kwargs): # user = kwargs["instance"] # if kwargs["created"]: # ... def create_user_profile(sender, instance, created, **kwargs): """ :param sender: Class User. :param instance: The user instance. """ if created: # Seems the following also works: # UserProfile.objects.create(user=instance) # TODO: Which is correct or better? profile = UserProfile(user=instance) profile.save() post_save.connect(create_user_profile, sender=User, dispatch_uid="users-profilecreation-signal")


Esto me ayudó: primary_key = True

class UserProfile(models.Model): user = models.OneToOneField(User, unique=True, primary_key=True, related_name="user") phone = models.CharField((''phone''),max_length=30, blank=False, null=True) user_building = models.ManyToManyField(Building, blank=True) added_by = models.ForeignKey(User, blank=True, null=True, related_name="added")


Puede obtener el perfil extendido que se creará cuando se acceda por primera vez para cada usuario en su lugar:

from django.db import models from django.contrib.auth.models import User class UserProfile(models.Model): user = models.ForeignKey(User, unique=True) additional_info_field = models.CharField(max_length=50) User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0])

luego usa

from django.contrib.auth.models import User user = User.objects.get(pk=1) user.profile.additional_info_field

ref: http://www.codekoala.com/blog/2009/quick-django-tip-user-profiles/


Puedes implementarlo usando post_save en el usuario:

from django.db.models.signals import post_save from models import UserProfile from django.contrib.auth.models import User def create_profile(sender, **kwargs): user = kwargs["instance"] if kwargs["created"]: profile = users.models.UserProfile() profile.setUser(sender) profile.save() post_save.connect(create_profile, sender=User)

Editar:
Otra posible solución, que se prueba y funciona (la estoy usando en mi sitio):

from django.db import models from django.contrib.auth.models import User from django.db.models.signals import post_save def create_profile(sender, **kwargs): user = kwargs["instance"] if kwargs["created"]: up = UserProfile(user=user, stuff=1, thing=2) up.save() post_save.connect(create_profile, sender=User)


Actualización para 2018:

Esta pregunta ha recogido muchas opiniones, tal vez es hora de una actualización.

Esta es la última versión de la última Django.

from django.dispatch import receiver from django.db.models.signals import post_save from django.conf import settings from models import UserProfile @receiver(post_save, sender=settings.AUTH_USER_MODEL) def create_user_profile(sender, instance=None, created=False, **kwargs): if created: UserProfile.objects.create(user=instance)