Django rest-auth allauth注册电子邮件,名字和姓氏,没有用户名

Thi*_*ker 20 django django-rest-framework django-allauth django-rest-auth

我正在使用django-rest-auth和allauth在我的django应用程序中登录和注册.我没有为登录或注册编写任何额外的单行代码.使用emailid和提供的密码注册成功.

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

在我可浏览的注册api中,我得到以下内容:

在此输入图像描述

除了这些字段,我想要first_name和last_name(默认的auth_user表有这些列),这样我新创建的auth_user也会设置这些字段以及电子邮件和散列密码.

我怎样才能做到这一点?这个可浏览的表单本身并不那么重要,但能够存储first_name和last_name是我主要需要的.

小智 28

  1. 确保你ACCOUNT_USERNAME_REQUIRED = Falsesettings.py文件中有.

  2. 对于first_namelast_name你需要编写一个自定义RegisterSerializer(https://github.com/Tivix/django-rest-auth/blob/master/rest_auth/registration/serializers.py#L166)

这是一个示例代码 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
Run Code Online (Sandbox Code Playgroud)
  1. settings.py确保你添加引用新的串行.

    REST_AUTH_REGISTER_SERIALIZERS = {
            'REGISTER_SERIALIZER': 'path.to.RegisterSerializer',
    }
    
    Run Code Online (Sandbox Code Playgroud)

  • 解决了!我将user.profile.save()更改为user.save()非常感谢! (2认同)

小智 13

你也可以覆盖custom_signup上的方法RegisterSerializer,其目的是为了这个目的.

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
Run Code Online (Sandbox Code Playgroud)

然后使用以下内容 urls.py

url(r'^rest-auth/registration/name-registration/$', NameRegistrationView.as_view(), name="rest_name_register")
Run Code Online (Sandbox Code Playgroud)

或者REGISTER_SERIALIZER进入settings.py

REST_AUTH_REGISTER_SERIALIZERS = {
    'REGISTER_SERIALIZER': 'path.to.RegisterSerializer',
}
Run Code Online (Sandbox Code Playgroud)


小智 10

更优雅的解决方案是从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
Run Code Online (Sandbox Code Playgroud)

  • 效果很好,但是我认为保存功能不是必需的,对吗? (4认同)
  • 我可以确认确实不需要保存功能,但也许您需要一个自定义适配器。[这个答案逐步解释了一个不错的步骤](/sf/answers/3783773171/)。 (2认同)