Cómo personalizar el perfil de usuario al usar django-allauth
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 proporcionada paradjango-allauth
:
ACCOUNT_SIGNUP_FORM_CLASS
(=None
)Una cadena que apunta a una clase de formulario personalizado (p. ej.
‘myapp.forms.SignupForm’
) que se utiliza durante el registro para solicitar al usuario información adicional (p. ej., suscripción al boletín informativo, fecha de nacimiento). Esta clase debe implementar un‘save’
método, aceptando al 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 personalizado? ¿Necesito agregar también una clase de modelo con un enlace al objeto de usuario como este ?
Supongamos que desea preguntarle al usuario su nombre/apellido durante el registro. Deberá colocar estos campos en su propio formulario, 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 tu configuración apunta a este formulario:
ACCOUNT_SIGNUP_FORM_CLASS = 'yourproject.yourapp.forms.SignupForm'
Tenga en cuenta que SignupForm
no se puede definir en el mismo archivo que las anulaciones de formulario a través ACCOUNT_FORMS
de o SOCIALACCOUNT_FORMS
, porque eso provocaría un error de importación circular.
Eso es todo.
Al utilizar la solución sugerida por pennersr, recibí una advertencia de desaprobació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 obsoleto en favor de un método de registro (solicitud, usuario) def.
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()
Esto es lo que funcionó para mí combinando algunas de las otras respuestas (ninguna de ellas está 100% completa y SECO).
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 manera usa los formularios del modelo para que esté SECO y usa el nuevo def signup
. Intenté ponerlo 'myproject.myapp.forms.SignupForm'
pero de alguna manera resultó en un error.
@Shreyas: Puede que la siguiente solución no sea la más limpia, pero funciona. 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()