2016-03-15 13 views
0

我已經使用Facebook作爲社交賬戶提供商實現了Django-allauth,因爲它提供了有關其用戶的大量信息。 下面是我的自定義註冊表單:Django-allauth信號/適配器流程如何工作?

ACCOUNT_SIGNUP_FORM_CLASS = 'profiles.forms.MySignupForm'

class MySignupForm(forms.ModelForm): 
class Meta: 
    model = get_user_model() 
    fields = ['email', 'first_name', 'last_name'] 

def __init__(self, *args, **kwargs): 
    super(MySignupForm, self).__init__(*args, **kwargs) 
    self.helper = FormHelper() 
    self.fields["email"].widget.input_type = "email" # ugly hack 
    self.helper.form_method = "POST" 
    self.helper.form_action = "account_signup" 
    self.helper.form_id = "signup_form" 
    self.helper.form_class = "signup" 
    self.helper.layout = Layout(
     Field('email', placeholder="Enter Email", autofocus=""), 
     Field('first_name', placeholder="Enter First Name"), 
     Field('last_name', placeholder="Enter Last Name"), 
     Field('password1', placeholder="Enter Password"), 
     Field('password2', placeholder="Re-enter Password"), 
     Submit('sign_up', 'Sign up', css_class="btn-warning"), 
    ) 

def signup(self, request, user): 
    user.first_name = self.cleaned_data['first_name'] 
    user.last_name = self.cleaned_data['last_name'] 
    user.email = self.cleaned_data['email'] 
    user.save() 

*What else can be added here in signup form ??? or to do the processing on received input i need to write adapter ??* 

我有以下實現信號接收器。

@receiver(user_signed_up) 
def set_initial_user_names(request, user, sociallogin=None, **kwargs): 
    if sociallogin: 
     ***grab the data*** 
     email_verified = sociallogin.account.extra_data['verified'] 
     profile = models.Profile(user=user, avatar_url=picture_url, email_verified=email_verified) 
     profile.save() <--- *saving custom user profile here* 
     from allauth.account.models import EmailAddress 
     emails = EmailAddress.objects.filter(user=user, email=user.email) 
     for email in emails: 
      email.verified = email_verified 
      email.save() <--- *saving allauth Email Address instance.* 
     user.guess_display_name() 
     user.save() <----- *saving custom user model based on email address.* 

現在,如果你看看電子郵件是由社會帳戶(臉譜)如果是我更新的allauth郵箱地址的實例驗證我正在覈實。

但它發生兩次。 allauth在登錄/註冊過程中已經更新了電子郵件地址實例(account_emailaddress)。因此,對於account_emailaddress表,數據庫被擊中兩次。

我想控制這種情況下我自己,這樣它只做一次..
答案是適配器,但如果我寫適配器,發生了什麼信號接收器?
有人可以告訴我的適配器/信號流?應該如何實施。 ?? 我已經通過文件,但仍然會很好,如果我得到一些方向的流量就像在哪個階段我可以控制!

回答

2

請勿使用ModelForm作爲您的自定義註冊表單,因爲allauth需要負責構建User實例並保存它。使其成爲一種簡單的形式,簡單地從django.forms.Form派生。僅在註冊期間需要添加額外輸入的情況下才使用它。看看你的表格,似乎你沒有添加任何額外的字段,所以你可能根本不需要自定義表單。

使用下面的表格要求用戶提供其姓/名:

class SignupForm(forms.Form): 
    first_name = forms.CharField(max_length=30) 
    last_name = forms.CharField(max_length=30) 

    def signup(self, request, user): 
     user.first_name = self.cleaned_data['first_name'] 
     user.last_name = self.cleaned_data['last_name'] 
     user.save() 
+0

我使用自定義用戶模型電子郵件作爲用戶名和第一/姓氏爲必填項。 如果我不使用自定義註冊表單,那麼所有auth註冊表單隻會要求輸入電子郵件和密碼。 也可以評論我上面提到的接收器? 感謝您的幫助。 –

+0

另外我看到奇怪的行爲,當我使用django.forms.Form vs django.forms.ModelForm 如果我只使用django.forms.Form然後第一/姓氏不會出現在註冊形式,但如果我使用django.forms .ModelForm它確實.. 困惑... –

+0

看到我的更新的答案爲示例的名字/姓氏。至於Form vs ModelForm,我的答案是 - ModelForm不會被使用,它會讓你陷入困境。用戶模型已經由allauth處理,自定義SignupForm僅用於其他問題。 – pennersr