如何在使用django-allauth时自定义用户configuration文件
我有一个django-allauth应用程序的django项目。 我需要在注册时从用户那里收集更多的数据。 我在这里遇到了类似的问题,但不幸的是,没有人回答configuration文件的定制部分。
根据为django-allauth
提供的文档 :
ACCOUNT_SIGNUP_FORM_CLASS
(=None
)指向注册期间使用的自定义表单类(例如
'myapp.forms.SignupForm'
)的string,以询问用户是否需要额外的input(如简报注册,出生date)。 这个类应该实现一个'save'
方法,接受新注册的用户作为唯一的参数。
我是django的新手,我正在为此而苦苦挣扎。 有人可以提供这样一个自定义表单类的例子吗? 我是否需要添加一个模型类以及链接到这样的用户对象?
假设你想在注册期间询问用户的名字/姓氏。 你需要把这些字段放在你自己的表单中,像这样:
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'
就这样。
使用pennersrbuild议的解决scheme,我得到了一个DeprecationWarning:
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'
这样它使用的模型forms,所以它是干的,并使用新的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原则。
@Shreyas:下面的解决scheme可能不是最干净的,但它的工作原理。 请让我知道,如果你有任何build议,进一步清理。
要添加不属于默认用户configuration文件的信息,请先在yourapp / models.py中创build一个模型。 阅读一般的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中创build一个表单:
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()
我已经尝试了许多不同的教程,他们都缺less一些东西,重复不必要的代码或做怪异的事情,以下我的解决scheme,join我find的所有选项,它的工作,我已经把它在生产,但它仍然没有说服我,因为我希望在我附加到用户创build的函数内部接收first_name和last_name,以避免在表单中创build一个configuration文件,但我不能,由我走,我认为这将帮助你。
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'
创build一个用户为OneToOneField的configuration文件模型
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'))