readthedocs - django allauth login with email
Cómo personalizar el perfil de usuario cuando se usa django-allauth (7)
@Shreyas: la solución a continuación puede no ser la más limpia, pero funciona. Por favor, avíseme si tiene alguna sugerencia para limpiarlo más.
Para agregar información que no pertenece al perfil de usuario predeterminado, primero cree un modelo en yourapp / models.py. Lea los documentos generales de django para obtener más información al respecto, pero básicamente:
from django.db import models
class UserProfile(models.Model):
user = models.OneToOneField(User, related_name=''profile'')
organisation = models.CharField(organisation, max_length=100, blank=True)
Luego crea un formulario en yourapp / forms.py:
from django import forms
class SignupForm(forms.Form):
first_name = forms.CharField(max_length=30, label=''Voornaam'')
last_name = forms.CharField(max_length=30, label=''Achternaam'')
organisation = forms.CharField(max_length=20, label=''organisation'')
def signup(self, request, user):
user.first_name = self.cleaned_data[''first_name'']
user.last_name = self.cleaned_data[''last_name'']
# Replace ''profile'' below with the related_name on the OneToOneField linking back to the User model
up = user.profile
up.organisation = self.cleaned_data[''organisation'']
user.save()
up.save()
Tengo un proyecto django con la aplicación django-allauth. Necesito recopilar datos adicionales del usuario al registrarse. Me encontré con una pregunta similar aquí, pero desafortunadamente, nadie respondió la parte de personalización del perfil.
Según la documentación provista para django-allauth
:
ACCOUNT_SIGNUP_FORM_CLASS
(=None
)Una cadena que apunta a una clase de formulario personalizada (por ejemplo,
''myapp.forms.SignupForm''
) que se utiliza durante el registro para solicitar al usuario información adicional (por ejemplo, suscripción al boletín de noticias, fecha de nacimiento). Esta clase debe implementar un método''save''
, aceptando el usuario recién registrado como su único parámetro.
Soy nuevo en django y estoy luchando con esto. ¿Alguien puede dar un ejemplo de una clase de formulario personalizada? ¿Debo agregar también una clase de modelo con un enlace al objeto de usuario como this ?
Crear un modelo de perfil con el usuario como OneToOneField
class Profile(models.Model):
user = models.OneToOneField(User, verbose_name=_(''user''), related_name=''profiles'')
first_name=models.CharField(_("First Name"), max_length=150)
last_name=models.CharField(_("Last Name"), max_length=150)
mugshot = ImageField(_(''mugshot''), upload_to = upload_to, blank=True)
phone= models.CharField(_("Phone Number"), max_length=100)
security_question = models.ForeignKey(SecurityQuestion, related_name=''security_question'')
answer=models.CharField(_("Answer"), max_length=200)
recovery_number= models.CharField(_("Recovery Mobile Number"), max_length=100)
city=models.ForeignKey(City,related_name=''city'', blank=True, null=True, help_text=_(''Select your City''))
location=models.ForeignKey(Country,related_name=''location'', blank=True, null=True, help_text=_(''Select your Location''))
En tus users/forms.py
pones:
from django.contrib.auth import get_user_model
class SignupForm(forms.ModelForm):
class Meta:
model = get_user_model()
fields = [''first_name'', ''last_name'']
def save(self, user):
user.save()
En settings.py pones:
ACCOUNT_SIGNUP_FORM_CLASS = ''users.forms.SignupForm''
De esta forma, no se rompe el principio DRY por multiplicidad Definición de campos de modelos de usuario.
Esto es lo que funcionó para mí combinando algunas de las otras respuestas (ninguna de ellas es 100% completa y SECA).
En yourapp/forms.py
:
from django.contrib.auth import get_user_model
from django import forms
class SignupForm(forms.ModelForm):
class Meta:
model = get_user_model()
fields = [''first_name'', ''last_name'']
def signup(self, request, user):
user.first_name = self.cleaned_data[''first_name'']
user.last_name = self.cleaned_data[''last_name'']
user.save()
Y en settings.py
:
ACCOUNT_SIGNUP_FORM_CLASS = ''yourapp.forms.SignupForm''
De esta forma, utiliza los formularios del modelo para que sea SECO y utiliza el nuevo def signup
. Intenté poner ''myproject.myapp.forms.SignupForm''
pero eso ocasionó un error de alguna manera.
He probado muchos tutoriales diferentes y a todos les falta algo, repetir código innecesario o hacer cosas raras, a continuación sigue mi solución que reúne todas las opciones que he encontrado, está funcionando, ya lo he puesto en producción PERO Todavía no me convence porque esperaría recibir first_name y last_name dentro de las funciones que adjunté a Users create para evitar crear un perfil dentro del formulario, pero no pude, por el momento creo que te ayudará.
Models.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
bio = models.TextField(max_length=500, blank=True)
nationality = models.CharField(max_length=2, choices=COUNTRIES)
gender = models.CharField(max_length=1, choices=GENDERS)
def __str__(self):
return self.user.first_name
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
instance.profile.save()
Forms.py
class SignupForm(forms.ModelForm):
first_name = forms.CharField(max_length=100)
last_name = forms.CharField(max_length=100)
class Meta:
model = Profile
fields = (''first_name'', ''last_name'', ''nationality'', ''gender'')
def signup(self, request, user):
# Save your user
user.first_name = self.cleaned_data[''first_name'']
user.last_name = self.cleaned_data[''last_name'']
user.save()
user.profile.nationality = self.cleaned_data[''nationality'']
user.profile.gender = self.cleaned_data[''gender'']
user.profile.save()
Settings.py
ACCOUNT_SIGNUP_FORM_CLASS = ''apps.profile.forms.SignupForm''
Supongamos que desea preguntar al usuario su nombre / apellido durante el registro. Tendrá que poner estos campos en su propia forma, así:
class SignupForm(forms.Form):
first_name = forms.CharField(max_length=30, label=''Voornaam'')
last_name = forms.CharField(max_length=30, label=''Achternaam'')
def signup(self, request, user):
user.first_name = self.cleaned_data[''first_name'']
user.last_name = self.cleaned_data[''last_name'']
user.save()
Luego, en su configuración, apunte a esta forma:
ACCOUNT_SIGNUP_FORM_CLASS = ''yourproject.yourapp.forms.SignupForm''
Eso es todo.
Utilizando la solución sugerida por pennersr recibí una advertencia de depreciación:
DeprecationWarning: The custom signup form must offer a def signup(self, request, user) method DeprecationWarning)
Esto se debe a que a partir de la versión 0.15, el método de guardar ha quedado en desuso en favor de un método de suscripción def (solicitud, usuario).
Entonces para resolver esto, el código del ejemplo debería ser así:
class SignupForm(forms.Form):
first_name = forms.CharField(max_length=30, label=''Voornaam'')
last_name = forms.CharField(max_length=30, label=''Achternaam'')
def signup(self, request, user):
user.first_name = self.cleaned_data[''first_name'']
user.last_name = self.cleaned_data[''last_name'']
user.save()