Django allauth,多种形式注册

时间:2017-09-10 19:38:41

标签: django django-allauth

我正在尝试使用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'),

1 个答案:

答案 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]首先保存它的想法是因为如果条款和条件发生变化,我们可以更改字段的值并拒绝登录,直到它再次被勾选。

相关问题