Django rest auth allauth注册,使用电子邮件、名字和姓氏,不使用用户名

Django rest auth allauth注册,使用电子邮件、名字和姓氏,不使用用户名,django,django-rest-framework,django-allauth,django-rest-auth,Django,Django Rest Framework,Django Allauth,Django Rest Auth,我正在使用django rest auth和allauth在我的django应用程序中进行登录和注册。我还没有写任何额外的代码,我自己的登录或注册行。使用emailid和提供的密码注册成功 我没有使用用户名进行身份验证,而是使用电子邮件 在用于注册的可浏览api中,我得到以下信息: 除了这些字段之外,我还希望有first_name和last_name(默认的auth_user表中有这些列),以便我新创建的auth_user还可以设置这些字段以及电子邮件和哈希密码 我怎样才能做到这一点?这个可浏

我正在使用django rest auth和allauth在我的django应用程序中进行登录和注册。我还没有写任何额外的代码,我自己的登录或注册行。使用emailid和提供的密码注册成功

我没有使用用户名进行身份验证,而是使用电子邮件

在用于注册的可浏览api中,我得到以下信息:

除了这些字段之外,我还希望有first_name和last_name(默认的auth_user表中有这些列),以便我新创建的auth_user还可以设置这些字段以及电子邮件和哈希密码

我怎样才能做到这一点?这个可浏览表单本身并不重要,但能够存储名字和姓氏是我主要需要的

  • 确保在
    settings.py
    文件中有
    ACCOUNT\u USERNAME\u REQUIRED=False

  • 对于
    first\u name
    last\u name
    ,您需要编写一个自定义
    注册表序列化程序()

  • 下面是
    serializers.py的示例代码

    from allauth.account import app_settings as allauth_settings
    from allauth.utils import email_address_exists
    from allauth.account.adapter import get_adapter
    from allauth.account.utils import setup_user_email
    
    class RegisterSerializer(serializers.Serializer):
        email = serializers.EmailField(required=allauth_settings.EMAIL_REQUIRED)
        first_name = serializers.CharField(required=True, write_only=True)
        last_name = serializers.CharField(required=True, write_only=True)
        password1 = serializers.CharField(required=True, write_only=True)
        password2 = serializers.CharField(required=True, write_only=True)
    
        def validate_email(self, email):
            email = get_adapter().clean_email(email)
            if allauth_settings.UNIQUE_EMAIL:
                if email and email_address_exists(email):
                    raise serializers.ValidationError(
                        _("A user is already registered with this e-mail address."))
            return email
    
        def validate_password1(self, password):
            return get_adapter().clean_password(password)
    
        def validate(self, data):
            if data['password1'] != data['password2']:
                raise serializers.ValidationError(
                    _("The two password fields didn't match."))
            return data
    
        def get_cleaned_data(self):
            return {
                'first_name': self.validated_data.get('first_name', ''),
                'last_name': self.validated_data.get('last_name', ''),
                'password1': self.validated_data.get('password1', ''),
                'email': self.validated_data.get('email', ''),
            }
    
        def save(self, request):
            adapter = get_adapter()
            user = adapter.new_user(request)
            self.cleaned_data = self.get_cleaned_data()
            adapter.save_user(request, user, self)
            setup_user_email(request, user, [])
            user.profile.save()
            return user
    
    url(r'^rest-auth/registration/name-registration/$', NameRegistrationView.as_view(), name="rest_name_register")
    
    REST_AUTH_REGISTER_SERIALIZERS = {
        'REGISTER_SERIALIZER': 'path.to.RegisterSerializer',
    }
    
  • settings.py
    中,确保添加以引用新的序列化程序

    REST_AUTH_REGISTER_SERIALIZERS = {
            'REGISTER_SERIALIZER': 'path.to.RegisterSerializer',
    }
    

  • 更优雅的解决方案是从RegisterSerializer继承,并根据需要进行扩展

    class MyRegisterSerializer(RegisterSerializer):
        first_name = serializers.CharField(required=True, write_only=True)
        last_name = serializers.CharField(required=True, write_only=True)
    
        def get_cleaned_data(self):
            return {
                'first_name': self.validated_data.get('first_name', ''),
                'last_name': self.validated_data.get('last_name', ''),
                'password1': self.validated_data.get('password1', ''),
                'email': self.validated_data.get('email', ''),
            }
    
        def save(self, request):
            adapter = get_adapter()
            user = adapter.new_user(request)
            self.cleaned_data = self.get_cleaned_data()
            adapter.save_user(request, user, self)
            setup_user_email(request, user, [])
            user.save()
            return user
    

    您也可以只覆盖
    注册表序列化程序
    上的
    自定义注册
    方法,该方法正是用于此目的的

    from rest_auth.registration.serializers import RegisterSerializer
    from rest_auth.registration.views import RegisterView
    from rest_framework import serializers
    
    
    class NameRegistrationSerializer(RegisterSerializer):
    
      first_name = serializers.CharField(required=False)
      last_name = serializers.CharField(required=False)
    
      def custom_signup(self, request, user):
        user.first_name = self.validated_data.get('first_name', '')
        user.last_name = self.validated_data.get('last_name', '')
        user.save(update_fields=['first_name', 'last_name'])
    
    
    class NameRegistrationView(RegisterView):
      serializer_class = NameRegistrationSerializer
    
    然后在
    url.py中使用以下内容

    from allauth.account import app_settings as allauth_settings
    from allauth.utils import email_address_exists
    from allauth.account.adapter import get_adapter
    from allauth.account.utils import setup_user_email
    
    class RegisterSerializer(serializers.Serializer):
        email = serializers.EmailField(required=allauth_settings.EMAIL_REQUIRED)
        first_name = serializers.CharField(required=True, write_only=True)
        last_name = serializers.CharField(required=True, write_only=True)
        password1 = serializers.CharField(required=True, write_only=True)
        password2 = serializers.CharField(required=True, write_only=True)
    
        def validate_email(self, email):
            email = get_adapter().clean_email(email)
            if allauth_settings.UNIQUE_EMAIL:
                if email and email_address_exists(email):
                    raise serializers.ValidationError(
                        _("A user is already registered with this e-mail address."))
            return email
    
        def validate_password1(self, password):
            return get_adapter().clean_password(password)
    
        def validate(self, data):
            if data['password1'] != data['password2']:
                raise serializers.ValidationError(
                    _("The two password fields didn't match."))
            return data
    
        def get_cleaned_data(self):
            return {
                'first_name': self.validated_data.get('first_name', ''),
                'last_name': self.validated_data.get('last_name', ''),
                'password1': self.validated_data.get('password1', ''),
                'email': self.validated_data.get('email', ''),
            }
    
        def save(self, request):
            adapter = get_adapter()
            user = adapter.new_user(request)
            self.cleaned_data = self.get_cleaned_data()
            adapter.save_user(request, user, self)
            setup_user_email(request, user, [])
            user.profile.save()
            return user
    
    url(r'^rest-auth/registration/name-registration/$', NameRegistrationView.as_view(), name="rest_name_register")
    
    REST_AUTH_REGISTER_SERIALIZERS = {
        'REGISTER_SERIALIZER': 'path.to.RegisterSerializer',
    }
    
    或在
    settings.py

    from allauth.account import app_settings as allauth_settings
    from allauth.utils import email_address_exists
    from allauth.account.adapter import get_adapter
    from allauth.account.utils import setup_user_email
    
    class RegisterSerializer(serializers.Serializer):
        email = serializers.EmailField(required=allauth_settings.EMAIL_REQUIRED)
        first_name = serializers.CharField(required=True, write_only=True)
        last_name = serializers.CharField(required=True, write_only=True)
        password1 = serializers.CharField(required=True, write_only=True)
        password2 = serializers.CharField(required=True, write_only=True)
    
        def validate_email(self, email):
            email = get_adapter().clean_email(email)
            if allauth_settings.UNIQUE_EMAIL:
                if email and email_address_exists(email):
                    raise serializers.ValidationError(
                        _("A user is already registered with this e-mail address."))
            return email
    
        def validate_password1(self, password):
            return get_adapter().clean_password(password)
    
        def validate(self, data):
            if data['password1'] != data['password2']:
                raise serializers.ValidationError(
                    _("The two password fields didn't match."))
            return data
    
        def get_cleaned_data(self):
            return {
                'first_name': self.validated_data.get('first_name', ''),
                'last_name': self.validated_data.get('last_name', ''),
                'password1': self.validated_data.get('password1', ''),
                'email': self.validated_data.get('email', ''),
            }
    
        def save(self, request):
            adapter = get_adapter()
            user = adapter.new_user(request)
            self.cleaned_data = self.get_cleaned_data()
            adapter.save_user(request, user, self)
            setup_user_email(request, user, [])
            user.profile.save()
            return user
    
    url(r'^rest-auth/registration/name-registration/$', NameRegistrationView.as_view(), name="rest_name_register")
    
    REST_AUTH_REGISTER_SERIALIZERS = {
        'REGISTER_SERIALIZER': 'path.to.RegisterSerializer',
    }
    

    就这些吗?视图中没有更改?这工作非常完美,用户以名字和姓氏保存!但是,我在User.profile.save()这一行看到一个错误,说“User”对象没有属性“profile”..已解决!我将user.profile.save()改为user.save(),非常感谢!使用最少的自定义代码就像一个符咒。我认为这是更优雅的解决方案。谢谢你的发帖。效果很好,但我认为保存功能不是必需的,对吗?是的,我也同意上面的评论。我可以确认保存功能确实不是必需的,但也许你需要一个自定义适配器。在谷歌上搜索同样的东西,发现这里的头像有相似之处:。不得不说抱歉:)这是一个更好的方法。只是一个建议:如果你只想覆盖默认的注册视图,你不需要视图。该死的,你救了我的一天