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

使用自定义User模型实现Django认证时用户变为Anonymous User问题求助

解决自定义Django用户模型导致用户变为Anonymous User的问题

嘿,我明白你在学校项目里用自定义User模型实现Django认证时碰到了用户变成Anonymous User的麻烦,这在自定义认证模型时确实是个高频踩坑点,我来帮你梳理下可能的原因和解决办法!

首先,先看你给出的代码片段,能发现几个关键问题,再结合Django自定义用户模型的要求,我们一步步来修正:

1. 必须正确配置AUTH_USER_MODEL

这是最基础却最容易忘的一步!在你的项目settings.py里,一定要添加这行配置,告诉Django使用你的自定义用户模型:

AUTH_USER_MODEL = "你的应用名.User"  # 比如如果你的User模型在名为accounts的app里,就写"accounts.User"

如果没加这行,Django会默认使用自带的User模型,自然无法识别你的自定义用户,导致登录后还是匿名。

2. 修正User模型的核心问题

你的自定义User模型继承了AbstractBaseUser,但缺少几个必要的配置和方法:

(1)删除重复的password字段

AbstractBaseUser已经自带了password字段,并且Django会自动处理密码的哈希存储。你自己定义的password = models.CharField(max_length=24)会覆盖这个逻辑,导致密码无法正确验证,登录失败后就会变成匿名用户,必须删掉这一行。

(2)添加自定义UserManager

AbstractBaseUser没有默认的对象管理器,你必须定义一个UserManager来处理用户的创建逻辑(包括普通用户和超级用户),否则无法创建用户、无法用createsuperuser命令:

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

class UserManager(BaseUserManager):
    def create_user(self, username, first_name, last_name, password=None):
        # 校验必填字段
        if not username:
            raise ValueError("用户名不能为空")
        if not first_name:
            raise ValueError("名字不能为空")
        if not last_name:
            raise ValueError("姓氏不能为空")
        
        # 创建用户实例
        user = self.model(
            username=username,
            first_name=first_name,
            last_name=last_name
        )
        # 用Django内置的set_password处理密码哈希
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, username, first_name, last_name, password):
        # 复用create_user方法创建超级用户,再添加权限
        user = self.create_user(
            username=username,
            first_name=first_name,
            last_name=last_name,
            password=password
        )
        # 添加必要的权限字段,根据你的需求调整
        user.is_admin = True
        user.is_active = True
        user.save(using=self._db)
        return user

然后在你的User模型里添加:

class User(AbstractBaseUser):
    userID = models.AutoField(primary_key=True)
    username = models.CharField(max_length=20, unique=True)
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=50)
    # 添加必要的权限状态字段
    is_active = models.BooleanField(default=True)  # 用户是否激活
    is_admin = models.BooleanField(default=False)  # 是否是管理员

    USERNAME_FIELD = "username"
    REQUIRED_FIELDS = ["first_name", "last_name"]

    # 绑定自定义管理器
    objects = UserManager()

    # 实现Django认证系统要求的方法
    def get_full_name(self):
        return f"{self.first_name} {self.last_name}"

    def get_short_name(self):
        return self.first_name

    # 权限相关方法,Django后台需要这些
    def has_perm(self, perm, obj=None):
        # 简单逻辑:管理员拥有所有权限
        return self.is_admin

    def has_module_perms(self, app_label):
        # 简单逻辑:管理员能访问所有应用
        return self.is_admin

    @property
    def is_staff(self):
        # 定义哪些用户能登录Django后台,这里让管理员都能登录
        return self.is_admin

3. 检查登录逻辑是否正确

确保你的登录视图里正确使用了Django的authenticate和login函数,这两个步骤缺一不可:

from django.contrib.auth import authenticate, login
from django.shortcuts import redirect, render

def login_view(request):
    if request.method == "POST":
        username = request.POST.get("username")
        password = request.POST.get("password")
        # 先验证用户账号密码是否正确
        user = authenticate(request, username=username, password=password)
        if user is not None:
            # 验证通过后,将用户绑定到当前会话
            login(request, user)
            return redirect("你的首页路由")  # 登录成功后跳转
        else:
            # 登录失败的提示
            return render(request, "login.html", {"error": "用户名或密码错误"})
    return render(request, "login.html")

如果跳过了login(request, user),或者authenticate返回None(比如密码不匹配),都会导致用户保持匿名状态。

4. 确认中间件配置完整

在settings.py的MIDDLEWARE里,必须包含以下两个中间件,它们负责处理用户会话和认证:

MIDDLEWARE = [
    # ... 其他中间件
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    # ... 其他中间件
]

如果缺失这两个,Django无法跟踪用户会话,自然识别不了登录后的用户。

5. 重置数据库迁移(如果之前有错误迁移)

如果你是中途修改的用户模型,可能存在迁移冲突。最简单的解决方式是:

  • 删除项目根目录的db.sqlite3文件(如果用的是SQLite)
  • 删除你的应用下migrations文件夹里除了__init__.py以外的所有文件
  • 重新执行迁移命令:
python manage.py makemigrations
python manage.py migrate

然后用python manage.py createsuperuser创建一个超级用户,测试登录Django后台是否正常。

按照这些步骤调整后,你的自定义用户模型应该就能正常工作,不会再出现Anonymous User的问题啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:33:16