我正在尝试使用django allauth创建一个多表单注册。 (我最初尝试过django向导,但选择退出,因为注册不一定是线性路径,具体取决于用户填写的早期表单数据)。 什么是让django allauth与多页注册一起工作的最佳方式?
我认为使用一系列表单视图,第一个创建用户并登录:
@require_http_methods(['GET', 'HEAD', 'POST'])
def profile_view(request, price_id):
form = ProfileForm()
if request.method == 'POST':
form = ProfileForm(request.POST)
if form.is_valid():
form.save()
user = authenticate(request, username=form.cleaned_data['email'],
password=form.cleaned_data['password1'])
login(request, user)
return redirect('users:supply_address')
return render(request, 'pages/signup.html', {'form': form})
后跟一系列类似的视图,这些视图需要登录,然后以使用django-allauth中的complete_signup
方法的视图结束。
@login_required
@require_http_methods(['GET', 'HEAD', 'POST'])
def direct_debit_view(request):
form = DirectDebitForm()
if request.method == 'POST':
form = DirectDebitForm(data=request.POST)
if form.is_valid():
request.session.update(form.cleaned_data)
complete_signup(request, user, settings.ACCOUNT_EMAIL_VERIFICATION,settings.LOGIN_REDIRECT_URL)
return redirect(settings.LOGIN_REDIRECT_URL)
return render(request, 'pages/signup_postcode.html', {'form': form})
覆盖用于登录django-allauth的URL以指向第一个注册视图。但是,我不确定这是否是最佳方法?
url(r'^account/signup/$', views.profile_view, name='profile'),
答案 0 :(得分:0)
所以基本的想法是given here。在我的情况下,我需要经常检查一个字段,因为它接受条款和条件。在项目的这个阶段处理自定义用户模型太烦人了,所以我把它作为一个要求并保存在配置文件中[1]。
配置文件模型(这对于所有配置文件模型都很愉快地工作很重要)具有null=True
或默认值的所有字段。这使我们能够以最少的甚至没有可用的信息以编程方式创建它们。
class BaseProfile(models.Model):
user = models.OneToOneField(
settings.AUTH_USER_MODEL, related_name='profile',
)
accepted_terms = models.BooleanField(
default=False, verbose_name=_('terms accepted'),
)
然后我们需要一个额外信息的表单。忽略account_type位,因为我们有不同的帐户类型,不同的配置文件模型添加到基本配置文件中:
from allauth.utils import get_request_param
from django import forms
from django.core.exceptions import ValidationError
from django.utils.translation import ugettext_lazy as _
from kernel.models import create_profile_for_user
class RequireTrueField(forms.BooleanField):
default_error_messages = {
'require_true': _('This field must be true')
}
widget = forms.CheckboxInput
def validate(self, value):
if not value:
raise ValidationError(self.error_messages['require_true'],
code='require_true')
class AccountSignupForm(forms.Form):
error_css_class = 'has-error'
accept_terms = RequireTrueField(
initial=False, error_messages={
'require_true': _('You must accept the terms and conditions')
}, label=_('I agree to the terms and conditions')
)
def signup(self, request, user):
account_type = get_request_param(request, 'account_type', '')
accepted = self.cleaned_data['accept_terms']
try:
profile, created = create_profile_for_user(
user, account_type, accepted_terms=accepted,
)
# XXX: This should always generate created as True. Verify?
except TypeError:
# XXX: spam someone
pass
在模板中,我们使用" next":
放置一个隐藏字段<input type="hidden" name="next" value="{% url 'kernel:profile_signup' %}"/>
哪个allauth将用作success_url
。请注意,如果设置了 ,则会创建用户,但表单不会重定向。
现在我们的用户拥有个人资料模型,数据量最少,可以提出下一批问题。对于每个阶段,在概要文件模型上实现BooleanField。
然后保护观点,需要一个活跃的帐户与所有布尔值勾选,
使用UserPassesTestMixin
。
[1]首先保存它的想法是因为如果条款和条件发生变化,我们可以更改字段的值并拒绝登录,直到它再次被勾选。