【问题标题】:How Django-allauth signal/adapter flow works ?Django-allauth 信号/适配器流如何工作?
【发布时间】:2023-04-04 01:29:01
【问题描述】:

我已经使用 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 表的数据库被命中两次。

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

【问题讨论】:

    标签: django django-allauth


    【解决方案1】:

    不要将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()
    

    【讨论】:

    • 我正在使用自定义用户模型,电子邮件作为用户名,名字/姓氏是必填字段。如果我不使用自定义注册表单,那么所有身份验证注册表单都只要求输入电子邮件和密码。你也可以评论我上面提到的接收器吗?感谢您的帮助。
    • 另外,当我使用 django.forms.Form vs django.forms.ModelForm 时,如果我只使用 django.forms.Form,那么我会看到奇怪的行为,然后名字/姓氏不会出现在注册表单中,但如果我使用 django.forms.ModelForm 它确实.. 困惑...
    • 查看我的更新答案以获取有关名字/姓氏的示例。至于Form vs ModelForm,我的回答是——不要使用ModelForm,它会给你带来麻烦。用户模型已由allauth 处理,自定义的 SignupForm 仅用于附加问题。
    猜你喜欢
    • 2021-04-21
    • 2019-01-01
    • 2014-06-09
    • 2018-12-29
    • 2011-06-30
    • 2022-10-14
    • 2018-06-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多