我一直在尝试为Allauth构建自己的SignupForm并继续遇到问题。
当我尝试使用这样的forms.py时:
class SocialSignupForm(forms.ModelForm):
class Meta:
model = Profile
exclude = ('user',)
def __init__(self, *args, **kwargs):
self.sociallogin = kwargs.pop('sociallogin')
user = self.sociallogin.user
username = forms.CharField(max_length=25, label="Username", help_text='', required=True)
视觉上,表单完全没有任何问题。但是,当我尝试提交表单时,我会得到USER_ID为空错误。据推测,save方法试图在创建用户之前保存配置文件。不知道如何更改它的顺序,并且只需要在初始保存后重新运行signup()方法。
我已经尝试过其他一些方法(覆盖form.Form和AllAuth的SocialSignUpForm),没有更好的运气(虽然有一组不同的错误)。
这里的任何输入/指导都会令人惊讶,这让我疯狂。
答案 0 :(得分:1)
据我了解,SocialSignupForm旨在为您自定义User
模型的表单,因此除非Profile
是您的用户模型(即它来自AbstractBaseUser
),你不能在这里使用它。
如果要自定义表单以添加配置文件信息,则应以相反的方向执行此操作。在表单上定义要用于配置文件的其他字段,但仍保留
class Meta:
model = User # or whatever your User model is
事实上,你甚至不应该定义一个Meta类,而是从SignupForm派生出来:
from allauth.account.forms import SignupForm
class MySignupForm(SignupForm):
...
然后,您可以覆盖custom_signup
或save
功能,尝试根据用户模型创建配置文件模型
或者考虑使用信号进行此操作。
答案 1 :(得分:0)
对于覆盖 allauth SignupForm,您应该按照以下步骤操作:
TEMPLATES
中的 settings.py
:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates'), os.path.join(BASE_DIR, 'templates', 'account')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
.../your_project_path/your_virtualenv_path/lib/python3.8/site-packages/allauth/templates/account
) 到名称为 templates
的新目录。
我的 templates
目录格式 imageACCOUNTS_FORMS = {
.
.
.
'signup': 'registerations.form.AllauthSignUpForm', # Notic: You must call your own AllauthSignUpForm
.
.
.
}
ACCOUNT_EMAIL_VERIFICATION = 'none'
4. 现在您已准备好自定义登录、注册和其他 allauth 模板。所以你需要在你的应用程序中创建 forms.py
文件并覆盖 allauth SignupForm
:
from allauth.account.forms import SignupForm
class AllauthSignUpForm(SignupForm):
def __init__(self, *args, **kwargs):
super(AllauthSignUpForm, self).__init__(*args, **kwargs)
self.fields['username'] = forms.CharField(
label='',
widget=forms.TextInput(
attrs={
'class': 'signup_name_inp text-right mb-4 border-top-0 border-right-0 border-left-0 rounded',
'placeholder': 'Username',
'dir': 'ltr',
'autocomplete': 'off'
}
),
)
self.fields['email'] = forms.EmailField(
label='',
widget=forms.EmailInput(
attrs={
'class': 'signup_mail_inp text-right mb-4 border-top-0 border-right-0 border-left-0 rounded',
'placeholder': 'email',
'dir': 'ltr',
'autocomplete':'off',
'required': 'True'
},
)
)
self.fields['password1'] = forms.CharField(
label='',
widget=forms.PasswordInput(
attrs={
'class': 'signup_pass_inp1 text-right mb-4 border-top-0 border-right-0 border-left-0 rounded',
'placeholder': 'password',
'dir': 'rtl',
'autocomplete': 'off',
}
)
)
self.fields['password2'] = forms.CharField(
label='',
widget=forms.PasswordInput(
attrs={
'class': 'signup_pass_inp2 text-right mb-4 border-top-0 border-right-0 border-left-0 rounded',
'placeholder': 'Repeat password',
'dir': 'rtl',
'autocomplete': 'off',
}
)
)
def save(self, request=None):
# Ensure you call the parent class's save.
# .save() returns a User object.
user = super(AllauthSignUpForm, self).save(request)
# Add your own processing here.
print(user.username)
# You must return the original result.
return user
from .form import AllauthSignUpForm
from allauth.account.views import SignupView
class AllauthSignUpView(SignupView):
template_name = 'account/signup.html'
form_class = AllauthSignUpForm
success_url = reverse_lazy('core:home')
def get_context_data(self, **kwargs):
context = super(AllauthSignUpView, self).get_context_data(**kwargs)
signUpForm = AllauthSignUpForm(self.request.POST or None)
context['form'] = signUpForm
return context