2017-09-10 94 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]將它保存在首位的想法是因爲如果條款和條件發生變化,我們可以更改該字段的值並拒絕登錄,直到再次打勾爲止。

相關問題