2017-09-10 57 views
0

我想创建一个多表单注册与django allauth。 (我最初尝试django向导,但选择退出,因为注册并不一定是线性路径,这取决于用户填写的早期表单数据)。 让django allauth能够使用多页面注册的最佳方式是什么?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

你需要一种不同的方法。第一种形式已经创建了一个可以登录的有效用户。因此,注册完成所有意图和目的。剩下的就是完成配置文件。这是可以的,以及大多数注册的工作方式,但是如果您不想在完成所有事情之前创建用户帐户,则需要使用会话。最终形式需要将字段联合起来,并部分由会话内容填充。 – Melvyn

+0

我开始沿着会话路线走,但是在json编码中不支持的类型中遇到了更多困难。我可以首先创建用户帐户,然后再向其中添加更多数据(虽然不是完美的情况),但我不希望在注册过程完成之前向用户发送电子邮件完了。如果用户没有完成注册并完成数据,那么我将能够看到包含不完整详细信息的用户帐户。 – Yunti

+0

我几乎在同一条船上,除了我有两个用户类型完全不同的配置文件模型。我通过使用“下一个”来看到一种方式。如果您在request.POST或request.GET中提供下一个,则可以覆盖重定向url。将它作为表单域传递是我现在采用的道路。如果没有人发出邀请,我会在完成所有工作后发布一些代码。 – Melvyn

回答

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 

在模板中,我们把一个隐藏字段与“未来”:

<input type="hidden" name="next" value="{% url 'kernel:profile_signup' %}"/> 

哪个allauth将用作success_url。请注意,如果它设置为而不是,用户将被创建,但表单不会重定向。

所以,现在我们有一个用户,一个简介模型,最小的数据,并可以问下一批问题。对于每个阶段,在配置文件模型上实现一个BooleanField。 然后警卫意见,需要一个积极的帐户与所有布尔值勾号, 使用UserPassesTestMixin

[1]将它保存在首位的想法是因为如果条款和条件发生变化,我们可以更改该字段的值并拒绝登录,直到再次打勾为止。

相关问题