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

Django Admin仅支持Shell创建的超级用户登录,普通用户登录失败及管理器报错

Django自定义用户模型登录问题排查

自定义SubUser模型代码

from django.contrib.auth.models import AbstractUser
from django.db import models
from django.conf import settings
from .managers import CustomUserManager

class SubUser(AbstractUser):
    if settings.DEBUG:
        parent_user_id = models.ForeignKey('self', on_delete=models.DO_NOTHING, null=True, blank=True)
    else:
        parent_user_id = models.ForeignKey('self', on_delete=models.RESTRICT, null=True, blank=True)

    # Timestamps
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    USERNAME_FIELD = "username"

    objects = CustomUserManager()

    def __str__(self):
        return self.username

CustomUserManager管理器代码

from django.contrib.auth.base_user import BaseUserManager

class CustomUserManager(BaseUserManager):
    def create_user(self, username, password=None, **extra_fields):
        user = self.model(username=username, **extra_fields)
        print(username)
        print(password)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, username, password=None, **extra_fields):
        user = self.create_user(username, password, **extra_fields)
        user.is_staff = True
        user.is_superuser = True
        user.save(using=self._db)
        return user

遇到的问题

  • 通过Shell执行 u = SubUser.objects.create_superuser(username='asd', password='asdasd') 创建的超级用户可正常登录Admin后台,但执行 u = SubUser.objects.create_user(username='qwe', password='qweqwe') 创建的普通用户,虽数据库中密码已加密且记录正常,却无法登录Admin。
  • 直接实例化管理器创建用户时:
    user_manager = CustomUserManager()
    new_user = user_manager.create_user(username='qwe', password='qweqwe')
    
    触发报错:
    user.save(using=self._db)
    TypeError: 'NoneType' object is not callable
    

环境:Django 5.0.1 + sqlite3


问题原因与修复方案

1. 普通用户无法登录Admin

Admin后台仅允许is_staff=True的用户登录,你的create_user方法创建的用户默认is_staff为False,因此无法登录。

修复:

  • 若需要普通用户登录Admin,创建时显式传入is_staff=True:
    u = SubUser.objects.create_user(username='qwe', password='qweqwe', is_staff=True)
    
  • 也可以在create_user方法中添加默认值(按需选择):
    def create_user(self, username, password=None, **extra_fields):
        # 给is_staff设置默认值,根据业务需求调整
        extra_fields.setdefault('is_staff', False)
        extra_fields.setdefault('is_active', True)
        
        user = self.model(username=username, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user
    

2. 直接实例化管理器报错

BaseUserManager需要绑定到具体模型类才能正常工作,直接实例化时self._db未被初始化,导致保存操作失败。

修复:
永远通过模型的objects属性调用管理器方法,不要直接实例化管理器:

# 正确方式
new_user = SubUser.objects.create_user(username='qwe', password='qweqwe')

3. 额外优化建议

  • 确保settings.py中已配置自定义用户模型:AUTH_USER_MODEL = '你的应用名.SubUser'
  • 外键字段命名不符合Django惯例,建议将parent_user_id改为parent_user,Django会自动生成parent_user_id的数据库列名,更符合规范。

内容的提问来源于stack exchange,提问作者sergio jacobo jauregui

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 21:05:16