如何使用CustomUser结合dj_rest_auth实现仅通过邮箱和密码完成用户注册
如何使用CustomUser结合dj_rest_auth实现仅通过邮箱和密码完成用户注册
我来帮你搞定这个问题!要实现仅用邮箱和密码完成用户注册,咱们需要从自定义用户模型、django-allauth配置、自定义注册序列化器这几个核心环节调整,下面是具体的步骤和代码说明:
1. 确认自定义用户模型(CustomUser)的配置
首先你的accounts/models.py已经做了正确的设置,这里再强调几个关键要点:
- 把
USERNAME_FIELD设为email,让邮箱作为用户的唯一标识 REQUIRED_FIELDS设为空列表,不需要额外的必填字段- 自定义的
CustomUserManager确保创建用户时只需要邮箱和密码,逻辑完全没问题
# accounts/models.py from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager from django.db import models class CustomUserManager(BaseUserManager): def create_user(self, email, password=None, **extra_fields): if not email: raise ValueError('The Email field must be set') email = self.normalize_email(email) user = self.model(email=email, **extra_fields) user.set_password(password) user.save(using=self._db) return user def create_superuser(self, email, password=None, **extra_fields): extra_fields.setdefault('is_staff', True) extra_fields.setdefault('is_superuser', True) return self.create_user(email, password, **extra_fields) class CustomUser(AbstractBaseUser, PermissionsMixin): email = models.EmailField(unique=True) is_active = models.BooleanField(default=True) is_staff = models.BooleanField(default=False) date_joined = models.DateTimeField(auto_now_add=True) objects = CustomUserManager() USERNAME_FIELD = 'email' REQUIRED_FIELDS = [] def __str__(self): return self.email
2. 配置settings.py的关键参数
你的settings已经有了基础配置,这里需要补充和强调几个allauth和dj_rest_auth的核心设置,确保系统不再要求用户名:
# settings.py INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'accounts', 'rest_framework', 'dj_rest_auth', 'dj_rest_auth.registration', 'django.contrib.sites', 'allauth', 'allauth.account', 'allauth.socialaccount', 'rest_framework.authtoken' ] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'allauth.account.middleware.AccountMiddleware' ] SITE_ID = 1 AUTH_USER_MODEL = 'accounts.CustomUser' # 关键:告诉allauth我们不用username字段 ACCOUNT_USER_MODEL_USERNAME_FIELD = None ACCOUNT_USERNAME_REQUIRED = False # 用邮箱作为认证方式 ACCOUNT_AUTHENTICATION_METHOD = 'email' # 邮箱必须填写 ACCOUNT_EMAIL_REQUIRED = True # 关闭邮箱验证(根据需求可以改成'mandatory'或'optional') ACCOUNT_EMAIL_VERIFICATION = 'none' # 指定自定义的注册序列化器 REST_AUTH_REGISTER_SERIALIZERS = { 'REGISTER_SERIALIZER': 'accounts.serializers.CustomRegisterSerializer', }
3. 自定义注册序列化器(CustomRegisterSerializer)
默认的RegisterSerializer会要求用户名,所以我们需要自定义一个序列化器,移除username字段,只保留邮箱和密码相关字段,你的更新后的版本已经很完善了,这里再说明一下逻辑:
# accounts/serializers.py from django.contrib.auth import get_user_model from rest_framework import serializers from allauth.account.adapter import get_adapter from allauth.account.utils import setup_user_email User = get_user_model() class CustomRegisterSerializer(serializers.Serializer): # 显式设置username为None,避免序列化器要求该字段 username = None email = serializers.EmailField(required=True) password1 = serializers.CharField(write_only=True) password2 = serializers.CharField(write_only=True) 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 { 'email': self.validated_data.get('email', ''), 'password1': self.validated_data.get('password1', ''), } def custom_signup(self, request, user): pass def save(self, request): # 使用allauth的adapter创建用户 adapter = get_adapter() user = adapter.new_user(request) self.cleaned_data = self.get_cleaned_data() # 设置用户邮箱和密码 user.email = self.cleaned_data['email'] user.set_password(self.cleaned_data['password1']) user.save() # 初始化用户邮箱相关设置 setup_user_email(request, user, []) return user
4. 确认URL配置
你的project/urls.py已经正确配置了dj_rest_auth的路由,确保注册接口可以访问:
# project/urls.py from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('auth/', include('dj_rest_auth.urls')), path('auth/registration/', include('dj_rest_auth.registration.urls')), ]
测试注册接口
现在你可以用POST请求访问/auth/registration/,请求体只需要包含email、password1、password2三个参数,比如:
{ "email": "test@example.com", "password1": "yourStrongPassword123", "password2": "yourStrongPassword123" }
发送请求后就能成功创建用户,不需要提供用户名啦!
内容来源于stack exchange
相关产品推荐
相关产品推荐

