编辑
Please, do not waste your time reading the question... it is the wrong approach!
Look at my own answer for a step-by-step guide (with explanation) of the right solution
TL;博士
如何使用 django-allauth 为私有(private)和公司用户实现注册?
我正在遵循的方法(正确吗?)
我有以下
models
:class PrivateUser(models.Model):
"""Models a private user account"""
user = models.OneToOneField(User, on_delete=models.CASCADE)
class CompanyUser(models.Model):
"""Models the company's contact person user account"""
user = models.OneToOneField(User, on_delete=models.CASCADE)
class Company(models.Model):
"""Models the company attributes"""
contact_person = models.OneToOneField(User, related_name='company')
name = models.CharField(max_length=50, null=False, blank=False)
vat_no = models.CharField(
# some config and validators
)
# ... other non-relevant fields
现在,我必须区分这两个用户
PrivateUser
和 CompanyUser
在 django-allauth 的注册过程中,只有一个 official django-allauth documentation 中指定的注册表单:ACCOUNT_SIGNUP_FORM_CLASS (=None)
A string pointing to a custom form class (e.g.
myapp.forms.SignupForm
) that is used during signup to ask the user for additional input (e.g. newsletter signup, birth date). This class should implement adef signup(self, request, user)
method, where user represents the newly signed up user.
因此,为了创建一个独特的表单,我创建了一个抽象模型类,其中包含所有
来自
PrivateUser
的字段和 CompanyUser
加一(注意 user_type
字段):class AbstractComprehensiveUser(models.Model):
"""
Little hackish model class needed to handle one single sign up
form for multiple users
"""
USER_TYPE_CHOICES = (
('private', 'Private'),
('company', 'Company'),
)
user_type = models.CharField(
max_length=10,
blank=False,
choices=USER_TYPE_CHOICES
)
# Common fields for either private and company users
first_name = models.CharField(max_length=30, blank=False)
last_name = models.CharField(max_length=30, blank=False)
# Company specific fields
company_name = models.CharField(max_length=50, null=True, blank=True)
company_vat_no = models.CharField(
# some config and validators
null=True,
blank = True
)
# other non-relevant fields
class Meta:
abstract = True
注:所有非公共(public)字段在此类中具有属性
null=True
和 blank=True
.然后我创建了我的自定义
SignupForm
如下:class SignupForm(forms.ModelForm):
first_name = forms.CharField(max_length=30)
last_name = forms.CharField(max_length=30)
class Meta:
model = AbstractComprehensiveUser
fields = (
# Field to differentiate from private and company
# user sign up
'user_type',
# Common fields for either private and company users
'first_name', 'last_name',
# Company specifc fields
'company_name', 'company_vat_no', # etc etc
)
现在的想法是使用具有两种形式的模板:
user_type='private'
只是 first_name
和 last_name
字段 user_type='company'
以及来自 Company
的字段型号然后,在
SignupForm
我将收到 user_type
字段,我可以设置正确的形式,例如:class PrivateUserSignupForm(forms.ModelForm):
first_name = forms.CharField(max_length=30)
last_name = forms.CharField(max_length=30)
class Meta:
model = PrivateUser
fields = ('first_name', 'last_name')
问题是当我在
SignupForm.signup()
中检索数据时方法,User
模型已经写入数据库。我不想保存它,而只是:
signup
中的数据填充正确表单的方法(PrivateUserSignupForm
或 CompanyUserSignupForm
)问题是...
最佳答案
我有同样的问题。我需要将 allauth 用于不同的用户配置文件类型。我扩展了 allauth SignupView 并将其用作在我的情况下,我有一个 MemberProfile 和 PartnerProfile:
#profile models
class MemberProfile(models.Model):
user = models.OneToOneField(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
)
class PartnerProfile(models.Model):
user = models.OneToOneField(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
)
我想要每种类型的个人资料都有一个单独的注册页面。幸运的是,allauth SignupView 将用户存储在 form_value() 方法中的实例上。我将 SignupView 扩展为 ProfileView ,它需要一个 profile_class :
#mixin
from allauth.account.views import SignupView
from allauth.account.forms import SignupForm
class ProfileSignupView(SignupView):
template_name = 'profiles/register.html'
success_url = '' # profile specific success url
form_class = SignupForm
profile_class = None # profile class goes here
def form_valid(self, form):
response = super(ProfileSignupView, self).form_valid(form)
profile = self.profile_class(user=self.user)
profile.save()
return response
那么我的观点是这样的:
#views
from .mixins import ProfileSignupView
from .models import PartnerProfile, MemberProfile
class MemberSignupView(ProfileSignupView):
success_url = '/member/profile'
profile_class = MemberProfile
class PartnerSignupView(ProfileSignupView):
success_url = '/partner/profile'
profile_class = PartnerProfile
关于django - 使用 django-allauth 注册多用户类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44505242/