Comment personnaliser le profil utilisateur lors de l'utilisation de django-allauth
j'ai un projet django avec l'application django-allauth. Je dois recueillir des données supplémentaires de l'utilisateur à l'inscription. Je suis tombé sur une question similaire ici mais malheureusement, personne n'a répondu à la partie de personnalisation de profil.
Par la documentation django-allauth
:
ACCOUNT_SIGNUP_FORM_CLASS
(=None
)une corde pointant vers un classe de formulaire personnalisé (par exemple
‘myapp.forms.SignupForm’
) qui est utilisé lors de l'inscription pour demander à l'Utilisateur des informations supplémentaires (par exemple inscription à un bulletin d'information, date de naissance). Cette classe devrait implémenter une méthode‘save’
, en acceptant l'utilisateur nouvellement inscrit comme seul paramètre.
je suis nouveau à django et je suis aux prises avec ce. Quelqu'un peut-il fournir un exemple d'une telle classe de formulaire personnalisé? Est-ce que je dois ajouter une classe model aussi bien avec un lien vers l'objet utilisateur comme ceci ?
7 réponses
supposez que vous vouliez demander à l'utilisateur son prénom/nom lors de l'inscription. Vous aurez besoin de mettre ces champs dans votre propre forme, comme cela:
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()
ensuite, dans vos paramètres pointez vers ce formulaire:
ACCOUNT_SIGNUP_FORM_CLASS = 'yourproject.yourapp.forms.SignupForm'
C'est tout.
en utilisant la solution suggérée par pennersr je recevais un avertissement de dépréciation:
DeprecationWarning: The custom signup form must offer a def signup(self, request, user) method DeprecationWarning)
c'est parce que depuis la version 0.15 la méthode de sauvegarde a été dépréciée en faveur d'une méthode d'inscription def(requête, utilisateur).
donc pour résoudre ceci, le code de l'exemple devrait être comme ceci:
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()
voici ce qui a fonctionné pour moi en combinant quelques-unes des autres réponses (aucune n'est complète et sèche à 100%).
Dans 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()
et dans settings.py
:
ACCOUNT_SIGNUP_FORM_CLASS = 'yourapp.forms.SignupForm'
de cette façon il utilise les formes de modèle de sorte qu'il est sec, et utilise le nouveau def signup
. J'ai essayé de mettre 'myproject.myapp.forms.SignupForm'
mais ça a entraîné une erreur.
@Shreyas: la solution ci-dessous n'est peut-être pas la plus propre, mais elle fonctionne. S'il vous plaît laissez-moi savoir si vous avez des suggestions pour le nettoyer.
pour ajouter des informations qui n'appartiennent pas au profil d'utilisateur par défaut, créez d'abord un modèle dans yourapp/models.py. Pour en savoir plus, lisez les documents du général django:
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)
puis créer un formulaire dans 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()
dans votre users/forms.py
vous avez mis:
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()
In settings.py vous avez mis:
ACCOUNT_SIGNUP_FORM_CLASS = 'users.forms.SignupForm'
de cette façon vous ne brisez pas le principe sec par les champs de définition de modèles utilisateurs de multiplicité.
j'ai essayé beaucoup de différents tutoriels et chacun d'eux est manquant quelque chose, répétant le code inutile ou faire des choses bizarres, ci-dessous suit ma solution qui rejoint toutes les options que j'ai trouvé, il fonctionne, je l'ai déjà mis en production mais il toujours pas me convaincre parce que je m'attendrais à recevoir first_name et last_name à l'intérieur des fonctions que j'ai attaché aux utilisateurs créent pour éviter de créer un profil à l'intérieur de la forme mais je ne pouvais pas, par l'éloignement je pense qu'il aidera vous.
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'
créer un modèle de profil avec l'utilisateur comme 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'))