117 votes

Comment personnaliser le profil de l'utilisateur en utilisant django-allauth ?

J'ai un projet django avec l'application django-allauth. J'ai besoin de collecter des données supplémentaires auprès de l'utilisateur lors de l'inscription. Je suis tombé sur une question similaire ici Comment accéder aux noms et profils d'utilisateurs avec django-allauth mais malheureusement, personne n'a répondu à la partie personnalisation du profil.

Selon la documention fournie pour django-allauth

ACCOUNT_SIGNUP_FORM_CLASS (=None) Une chaîne de caractères pointant vers une classe de formulaire personnalisée (par exemple, 'myapp.forms.SignupForm') qui est utilisée pendant l'inscription pour demander à l'utilisateur des données supplémentaires (par exemple, inscription à la newsletter, date de naissance). Cette classe doit implémenter une méthode "save", acceptant l'utilisateur nouvellement inscrit comme seul paramètre.

Je suis nouveau dans le monde de Django et j'ai du mal avec ce problème. Quelqu'un peut-il me fournir un exemple d'une telle classe de formulaire personnalisé ? Dois-je également ajouter une classe de modèle avec un lien vers l'objet utilisateur comme ceci https://docs.djangoproject.com/en/dev/topics/auth/#storing-additional-information-about-users ?

180voto

pennersr Points 2151

Supposons que vous souhaitiez demander à l'utilisateur son nom et son prénom lors de l'inscription. Vous devrez placer ces champs dans votre propre formulaire, comme suit :

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 sur ce formulaire :

ACCOUNT_SIGNUP_FORM_CLASS = 'yourproject.yourapp.forms.SignupForm'

C'est tout.

11 votes

Merci. C'est toujours bon d'avoir des nouvelles de l'auteur original :). Dois-je créer une classe supplémentaire pour stocker ces informations ou allauth s'en charge-t-il automatiquement ?

13 votes

Cela dépend en fait des informations que vous demandez. Dans tous les cas, tout cela dépasse la portée d'allauth. Si vous demandez le nom/prénom comme dans l'exemple ci-dessus, vous n'avez pas besoin d'un modèle supplémentaire et vous pouvez placer les choses directement dans le modèle User. Si vous demandez la date de naissance de l'utilisateur, sa couleur préférée ou autre, vous devez configurer votre propre modèle de profil pour cela. Vous trouverez ici la marche à suivre : docs.djangoproject.com/fr/dev/topics/auth/

6 votes

C'est exactement ce que je cherchais - un champ supplémentaire comme la couleur préférée. Si je suis intéressé par la couleur préférée, je pense que je devrais créer une nouvelle classe UserProfile et utiliser l'utilisateur comme champ individuel et la couleur préférée comme champ supplémentaire. Dans ce cas, puis-je toujours utiliser le type de formulaire d'inscription que vous avez déclaré (avec la couleur préférée) ci-dessus et y associer la classe ACCOUNT_SIGNUP_FORM_CLASS ou dois-je créer le formulaire et gérer la sauvegarde des données dans mon propre code ?

24voto

ferrangb Points 502

En utilisant la solution suggérée par pennersr, je recevais un DeprecationWarning :

DeprecationWarning: The custom signup form must offer a def signup(self, request, user) method DeprecationWarning)

Cela s'explique par le fait que à partir de la version 0.15 la méthode save a été dépréciée au profit d'une méthode def signup(request, user).

Donc pour résoudre ce problème, 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()

2 votes

La réponse de @pennsesr a maintenant été modifiée pour utiliser signup au lieu de save .

20voto

Howardwlo Points 191

Voici ce qui a fonctionné pour moi, en combinant quelques-unes des autres réponses (aucune d'entre elles n'est 100% complète et DRY).

Sur 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 formulaires du modèle afin d'être DRY, et utilise la nouvelle fonction def signup . J'ai essayé de mettre 'myproject.myapp.forms.SignupForm' mais cela a donné lieu à une erreur d'une manière ou d'une autre.

0 votes

L'utilisation de 'yourapp.forms.SignupForm' au lieu de 'myproject.myapp.forms.SignupForm' a également fonctionné pour moi.

7voto

mark Points 41

@Shreyas : La solution ci-dessous n'est peut-être pas la plus propre, mais elle fonctionne. Veuillez me faire savoir si vous avez des suggestions pour la nettoyer davantage.

Pour ajouter des informations qui n'appartiennent pas au profil utilisateur par défaut, créez d'abord un modèle dans yourapp/models.py. Lisez la docs générale de django pour en savoir plus, mais en gros :

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)

Ensuite, créez 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()

0 votes

C'est exactement ce que j'ai fini par utiliser pour une application Django 2.0 qui utilise Wagtail CMS. Cela a fonctionné pour l'inscription normale, mais moins bien avec Social Auth, semble-t-il ?

1 votes

Comment ajouter ce champ supplémentaire à la page d'administration de l'utilisateur dans Wagtail ?

5voto

Adam Dobrawy Points 638

Dans votre users/forms.py vous mettez :

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()

Dans settings.py vous mettez :

ACCOUNT_SIGNUP_FORM_CLASS = 'users.forms.SignupForm'

De cette façon, vous n'enfreignez pas le principe DRY en définissant plusieurs champs de modèles d'utilisateurs.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X