Как настроить профиль пользователя при использовании django-allauth
у меня есть проект django с приложением django-allauth. Мне нужно собрать дополнительные данные от пользователя при регистрации. Я наткнулся на подобное вопрос но, к сожалению, никто не ответил на настройки профиля.
Per документация, предусмотренная для django-allauth
:
ACCOUNT_SIGNUP_FORM_CLASS
(=None
)строка, указывающая на пользовательский класс формы (например,
‘myapp.forms.SignupForm’
), который используется при регистрации пользователя для дополнительного ввода (например, регистрация бюллетеня, дата рождения). Этот класс должен реализовать‘save’
метод, принимая недавно подписанного пользователя в качестве единственного параметра.
Я новичок в django и борюсь с этим. Может ли кто-нибудь привести пример такого пользовательского класса формы? Нужно ли добавлять класс модели также со ссылкой на объект пользователя, например этой ?
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:
DeprecationWarning: The custom signup form must offer a def signup(self, request, user) method DeprecationWarning)
это так начиная с версии 0.15 метод save устарел в пользу метода регистрации def (запрос, пользователь).
чтобы решить эту проблему, код примера должен быть таким:
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'))