You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 09:34:34