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

Django自定义User模型迁移报错:AUTH_USER_MODEL未安装问题

问题分析与解决方案

核心原因

  1. 自定义User模型未适配Django认证系统:你创建的authentication.User仅继承了基础的models.Model,未继承Django认证所需的AbstractBaseUser或AbstractUser,导致无法被识别为合法的用户模型。
  2. 认证模型配置缺失/错误:即使手动添加AUTH_USER_MODEL,若未同步配置自定义模型的管理器、字段,或项目已执行过初始迁移,仍会触发错误。
  3. 视图方法调用错误:你在视图中使用了create_user()方法,但自定义模型未继承认证基类,自然没有该方法,触发Django内部的用户模型检查逻辑,导致报错。

分步解决方案

1. 修复自定义User模型

修改authentication/models.py,让模型继承认证基类并配置管理器:

from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin

class UserManager(BaseUserManager):
    def create_user(self, email, username, password=None, **extra_fields):
        if not email:
            raise ValueError('用户必须填写邮箱')
        email = self.normalize_email(email)
        user = self.model(email=email, username=username, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, username, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        return self.create_user(email, username, password, **extra_fields)

class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(
        verbose_name='邮箱',
        max_length=255,
        unique=True,
    )
    username = models.CharField(max_length=200, unique=True)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)

    objects = UserManager()

    # 指定登录验证用的字段
    USERNAME_FIELD = 'email'
    # 创建超级用户时必填的额外字段
    REQUIRED_FIELDS = ['username']

    def __str__(self):
        return self.email

2. 配置项目settings

在settings.py中完成两项配置:

  • 确保authentication app已加入INSTALLED_APPS:
INSTALLED_APPS = [
    # 保留原有app,添加以下行
    'authentication',
]
  • 指定自定义用户模型:
AUTH_USER_MODEL = 'authentication.User'

3. 重置数据库(关键步骤)

Django要求AUTH_USER_MODEL必须在第一次执行migrate前配置。如果你的项目已经执行过初始迁移,必须重置数据库:

# 停止容器
docker-compose down
# 删除数据库卷(若使用Docker卷持久化数据)
docker volume rm <你的项目数据库卷名>
# 重新启动容器并执行迁移
docker-compose up -d
docker-compose exec web python3 manage.py makemigrations
docker-compose exec web python3 manage.py migrate

4. 修复视图代码

修正视图中用户创建逻辑,确保使用自定义模型的管理器方法:

# authentication/views.py
from django.shortcuts import render, redirect
from django.contrib import messages
from django.core.validators import validate_email
from .models import User

def signup(request):
    if request.method == "POST":
        context = {'has_error': False, 'data': request.POST}
        email = request.POST.get('email')
        username = request.POST.get('username')
        password = request.POST.get('password')

        if len(password) < 6:
            messages.error(request, '密码长度至少6位')
            context['has_error'] = True

        try:
            validate_email(email)
        except:
            messages.error(request, '请输入合法邮箱')
            context['has_error'] = True

        if not username:
            messages.error(request, '用户名不能为空')
            context['has_error'] = True

        if User.objects.filter(username=username).exists():
            messages.error(request, '用户名已被占用')
            context['has_error'] = True

        if User.objects.filter(email=email).exists():
            messages.error(request, '邮箱已被注册')
            context['has_error'] = True

        if context['has_error']:
            return render(request, 'authentication/signup.html', context)

        # 使用自定义管理器的create_user方法,自动处理密码加密和保存
        User.objects.create_user(username=username, email=email, password=password)
        return redirect('login')  # 注册成功后跳转登录页

    return render(request, 'authentication/signup.html')

5. 解决主键警告

上述修改后的模型会自动生成主键字段,若仍需显式定义,可在User模型中添加:

id = models.AutoField(primary_key=True)

内容的提问来源于stack exchange,提问作者kurac

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 01:09:31