Как настроить профиль пользователя при использовании django-allauth



у меня есть проект django с приложением django-allauth. Мне нужно собрать дополнительные данные от пользователя при регистрации. Я столкнулся с подобным вопросом здесь, но, к сожалению, никто не ответил на часть настройки профиля.



на документация, предусмотренная для django-allauth:





ACCOUNT_SIGNUP_FORM_CLASS (=None)



строка, указывающая на пользовательский класс формы (например,‘myapp.forms.SignupForm’), который используется при регистрации, чтобы запросить у пользователя дополнительные ввод (например, подписка на рассылку новостей, дата рождения). Этот класс должен реализовать ‘save’ метод, принимающий только что подписанного пользователя в качестве своего единственного параметра.




Я новичок в Джанго и борюсь с этим. Может ли кто-нибудь привести пример такого пользовательского класса формы? Мне нужно добавить класс модели, а также со ссылкой на объект пользователя, как этой ?

722   7  

7 ответов:

Предположим, вы хотите спросить у пользователя его имя/фамилию во время регистрации. Вам нужно будет поместить эти поля в свою собственную форму, например:

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

затем в настройках укажите на эту форму:

ACCOUNT_SIGNUP_FORM_CLASS = 'yourproject.yourapp.forms.SignupForm'

вот и все.

используя решение, предложенное pennersr, я получал предупреждение об устаревании:

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

это так начиная с версии 0.15 метод сохранения устарел в пользу метода регистрации def (request, user).

Итак, чтобы решить эту проблему, код примера должен быть следующим:

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

вот что сработало для меня, объединив несколько других ответов (ни один из них не является 100% полным и сухим).

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

и settings.py:

ACCOUNT_SIGNUP_FORM_CLASS = 'yourapp.forms.SignupForm'

таким образом, он использует формы модели, чтобы она была сухой, и использует новый def signup. Я попробовал поставить 'myproject.myapp.forms.SignupForm' но это привело к ошибке как-то.

@Shreyas: ниже Решение может быть не самым чистым, но оно работает. Пожалуйста, дайте мне знать, если у вас есть какие-либо предложения, чтобы очистить его дальше.

чтобы добавить информацию, которая не относится к профилю пользователя по умолчанию, сначала создайте модель в yourapp/models.py. прочитайте общие документы 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)

затем создайте форму в 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()

в своем users/forms.py напишите:

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 вы ставите:

ACCOUNT_SIGNUP_FORM_CLASS = 'users.forms.SignupForm'

таким образом, вы не нарушаете сухой принцип определения полей множественности пользовательских моделей.

Я пробовал много разных учебников, и все они чего-то не хватает, повторяя ненужный код или делая странные вещи, ниже следует мое решение, которое объединяет все параметры, которые я нашел, оно работает, я уже поставил его в производство, но это все еще не убеждает меня, потому что я ожидал бы получить first_name и last_name внутри функций, которые я прикрепил к пользователям, чтобы избежать создания профиля внутри формы, но я не мог, вы.

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'

создать модель профиля с пользователем как 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'))

Comments

    Ничего не найдено.