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

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

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

ACCOUNT_SIGNUP_FORM_CLASS (= None )

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

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

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

 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 метод сохранения устарел в пользу метода определения регистрации (запроса, пользователя).

Чтобы решить эту проблему, код примера должен выглядеть следующим образом:

 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' но это как-то привело к ошибке.

В ваших 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() 

В settings.py вы ставите:

 ACCOUNT_SIGNUP_FORM_CLASS = 'users.forms.SignupForm' 

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

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

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

Я пробовал много разных учебников, и все они чего-то не хватает, повторяя ненужный код или делая странные вещи, ниже следуют моему решению, которое объединяет все варианты, которые я нашел, он работает, я уже поставил его в производство, НО это все еще не убеждающий меня, потому что я ожидал бы получить 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')) 
Давайте будем гением компьютера.