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
相关产品推荐
相关产品推荐

