it-swarm.com.de

So passen Sie das Benutzerprofil an, wenn Sie Django-allauth verwenden

Ich habe ein Django Projekt mit der Django-allauth App. Ich muss zusätzliche Daten vom Benutzer bei der Anmeldung sammeln. Ich bin auf ein ähnliches gestoßen Frage hier aber leider niemand hat den Teil zur Profilanpassung beantwortet.

Per die Dokumentation für Django-allauth :

ACCOUNT_SIGNUP_FORM_CLASS (= None)

Eine Zeichenfolge, die auf eine benutzerdefinierte Formularklasse zeigt (z. B. ‘myapp.forms.SignupForm’), Die während der Anmeldung verwendet wird, um den Benutzer um zusätzliche Eingaben zu bitten (z. B. Anmeldung zum Newsletter, Geburtsdatum). Diese Klasse sollte eine ‘save’ - Methode implementieren und den neu angemeldeten Benutzer als einzigen Parameter akzeptieren.

Ich bin neu in Django und habe Probleme damit. Kann jemand ein Beispiel für eine solche benutzerdefinierte Formularklasse bereitstellen? Muss ich auch eine Modellklasse mit einem Link zum Benutzerobjekt hinzufügen, z this ?

98
Shreyas

Angenommen, Sie möchten den Benutzer bei der Anmeldung nach seinem Vor-/Nachnamen fragen. Sie müssen diese Felder wie folgt in Ihr eigenes Formular einfügen:

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

Zeigen Sie dann in Ihren Einstellungen auf dieses Formular:

ACCOUNT_SIGNUP_FORM_CLASS = 'yourproject.yourapp.forms.SignupForm'

Das ist alles.

156
pennersr

Unter Verwendung der von pennersr vorgeschlagenen Lösung erhielt ich eine DeprecationWarning:

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

Dies liegt daran, dass ab Version 0.15 die Speichermethode zugunsten einer def-Anmeldemethode (Anfrage, Benutzer) abgelehnt wurde.

Um dies zu lösen, sollte der Code des Beispiels folgendermaßen aussehen:

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
ferrangb

Hier ist, was für mich gearbeitet hat, einige der anderen Antworten zu kombinieren (keine von ihnen ist 100% vollständig und TROCKEN).

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

Und in settings.py:

ACCOUNT_SIGNUP_FORM_CLASS = 'yourapp.forms.SignupForm'

Auf diese Weise werden die Modellformulare verwendet, sodass sie DRY sind, und das neue def signup. Ich habe versucht, 'myproject.myapp.forms.SignupForm' aber das führte irgendwie zu einem fehler.

15
Howardwlo

@ Shreyas: Die folgende Lösung ist möglicherweise nicht die sauberste, aber sie funktioniert. Bitte lassen Sie mich wissen, wenn Sie Vorschläge zur weiteren Bereinigung haben.

Um Informationen hinzuzufügen, die nicht zum Standardbenutzerprofil gehören, erstellen Sie zunächst ein Modell in yourapp/models.py. Lesen Sie die allgemeinen Django docs, um mehr darüber zu erfahren, aber im Grunde:

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)

Dann erstelle ein Formular in 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
mark

In deinem users/forms.py du legst:

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 setzen Sie:

ACCOUNT_SIGNUP_FORM_CLASS = 'users.forms.SignupForm'

Auf diese Weise wird das DRY Prinzip nicht durch die Definition von Benutzermodellfeldern aufgehoben.

4
Adam Dobrawy

Ich habe viele verschiedene Tutorials ausprobiert, und allen fehlt etwas, sie wiederholen unnötigen Code oder tun seltsame Dinge. Im Folgenden wird meine Lösung beschrieben, die alle von mir gefundenen Optionen vereint. Es funktioniert, ich habe es bereits in die Produktion aufgenommen, ABER es Ich kann mich immer noch nicht überzeugen, da ich erwarten würde, Vorname und Nachname in den Funktionen zu erhalten, die ich an Benutzer anhänge, um die Erstellung eines Profils innerhalb des Formulars zu vermeiden, aber ich konnte es nicht, da ich denke, dass es Ihnen helfen wird.

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

Einstellungen.py

ACCOUNT_SIGNUP_FORM_CLASS = 'apps.profile.forms.SignupForm'
4
Gregory