Django-allauth signal/adapter 流程如何运作?

How Django-allauth signal/adapter flow works ?

我已经使用 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 已经在 login/sign up 过程中更新了电子邮件地址实例 (account_emailaddress)。因此 account_emailaddress table.

数据库被命中两次

我想自己控制这个场景只做一次..
答案是适配器,但如果我写适配器,信号接收器会发生什么情况??
谁能告诉我 adapter/signal 流程??应该如何实施。 ?? 我已经阅读了文档,但如果我能在流程上得到一些指导,比如在哪个阶段我能控制什么,那就太好了!!

不要为您的自定义注册表单使用 ModelForm,因为 allauth 需要负责构建 User 实例并保存它。使它成为一个简单的形式,简单地从 django.forms.Form 派生。仅在您需要在注册期间添加额外输入的情况下使用它。查看您的表单,您似乎没有添加任何其他字段,因此您可能根本不需要自定义表单。

使用以下表格询问用户的 first/last 姓名:

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()