Как настроить профиль пользователя при использовании django-allauth
у меня есть проект django с приложением django-allauth. Мне нужно собрать дополнительные данные от пользователя при регистрации. Я столкнулся с подобным вопросом здесь, но, к сожалению, никто не ответил на часть настройки профиля.
на документация, предусмотренная для django-allauth:
ACCOUNT_SIGNUP_FORM_CLASS(=None)
строка, указывающая на пользовательский класс формы (например,
‘myapp.forms.SignupForm’), который используется при регистрации, чтобы запросить у пользователя дополнительные ввод (например, подписка на рассылку новостей, дата рождения). Этот класс должен реализовать‘save’метод, принимающий только что подписанного пользователя в качестве своего единственного параметра.
Я новичок в Джанго и борюсь с этим. Может ли кто-нибудь привести пример такого пользовательского класса формы? Мне нужно добавить класс модели, а также со ссылкой на объект пользователя, как этой ?
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