Django-allauth信号/适配器流如何工作?

时间:2016-03-15 15:28:07

标签: django django-allauth

我使用Facebook作为社交帐户提供商实施了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.*

现在,如果你看到我正在验证电子邮件是否经过社交帐户(Facebook)验证,那么我正在更新allauth的电子邮件地址实例。

但它发生了两次。 allauth在登录/注册过程中已经更新了电子邮件地址实例(account_emailaddress)。因此,对于account_emailaddress表,数据库会被点击两次。

我想自己控制这个场景,以便它只做一次..
答案是适配器,但如果我写适配器,信号接收器会发生什么? 有人能告诉我适配器/信号流吗?应该如何实施。 ?? 我已经完成了文档,但如果我在流程上得到一些方向,就像在哪个阶段我可以控制的那样,那将会很好!

1 个答案:

答案 0 :(得分:2)

请勿使用ModelForm作为自定义注册表单,因为allauth需要负责构建用户实例并进行保存。将其设为简单形式,只需从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()