2017-09-10 20 views
0

私はdjango allauthで複数フォームのサインアップを作成しようとしています。 (私はもともとdjango wizardを試しましたが、ユーザが記入した以前のフォームデータに応じてサインアップが必ずしも線形パスであるとは限りません)。 マルチページサインアップで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}) 

complete_signup django-allauthのメソッド。

@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エンコーディングでサポートされていないタイプではそれが難しくなりました。私は最初に作成されたユーザーアカウントでOKです。その後、完全な状況ではありませんが、さらにデータを追加すると、すべての登録プロセスが完了する前に電子メールをユーザーに送信したくありません。終了しました。ユーザーがサインアップを完了せずにデータを完成しないと、不完全な詳細を持つユーザーアカウントが表示されます。 – Yunti

+0

私はまったく同じボートに入っていますが、全く異なるプロファイルモデルを持つ2つのユーザータイプがあります。私は、 "次へ"の使用を通じて、方法を参照してください。 request.POSTまたはrequest.GETで次に指定すると、リダイレクトURLを上書きできます。フォームフィールドとして渡すことは、私が今取っている道です。誰もチャイムインしない場合、私はそれがすべて働いているときにいくつかのコードを投稿します。 – Melvyn

答えて

0

したがって、基本的な考えはgiven hereです。私の場合は、条件を受け入れているので、常に1つのフィールドをチェックする必要があります。プロジェクトのこの段階でカスタムユーザーモデルを扱うのは面倒なので、私はそれを要件とし、プロファイル[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' %}"/> 

すべてのオートはsuccess_urlとして使用します。 ではない場合、ユーザーは作成されますが、フォームはリダイレクトされません。

これで、プロファイルモデルと最小限のデータを持つユーザーがいるので、次のバッチの質問をすることができます。各ステージで、プロファイルモデルにBooleanFieldを実装します。 UserPassesTestMixinを使用して、すべてのブーリアンをチェックしてアクティブアカウントを必要とするガードビュー。

[1]条件を変更すると、フィールドの値を変更して再度ログインするまでログインを拒否できるため、最初に保存するという考えがあります。

関連する問題