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 ?

94
demandé sur Community 2012-09-06 19:30:15

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.

149
répondu pennersr 2014-07-20 21:08:35

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()
22
répondu ferrangb 2014-06-15 16:13:44

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.

14
répondu Howardwlo 2016-01-27 05:34:06

@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()
5
répondu mark 2016-07-27 15:29:07

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é.

4
répondu Adam Dobrawy 2015-07-12 11:56:27

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'
3
répondu Gregory 2017-04-08 19:58:12

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'))
-8
répondu Jubin Thomas 2012-09-06 15:38:58