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

创建自定义超级用户后无法登录Django Admin面板求助

自定义Django用户模型无法登录Admin面板的排查与解决

以下是针对你遇到的问题的分步排查方案,结合你提到的核心文件逐一验证:

1. 验证Settings.py配置

核心检查项:

  • 确认AUTH_USER_MODEL正确指向自定义用户模型:
    # settings.py
    AUTH_USER_MODEL = "your_app_name.CustomUser"  # 替换为实际的app和模型名
    
  • 确认AUTHENTICATION_BACKENDS包含自定义的邮箱认证后端(如果用邮箱登录):
    # settings.py
    AUTHENTICATION_BACKENDS = [
        "your_app_name.Authentication.EmailBackend",  # 自定义后端路径
        "django.contrib.auth.backends.ModelBackend",  # 可选,保留默认后端兼容
    ]
    

2. 检查自定义认证后端(Authentication.py)

确保authenticate方法正确验证邮箱、密码,且只返回具备staff权限的活跃用户:

# Authentication.py
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth import get_user_model
from django.db.models import Q

UserModel = get_user_model()

class EmailBackend(ModelBackend):
    def authenticate(self, request, username=None, password=None, **kwargs):
        # 这里的username参数对应前端传入的邮箱
        try:
            user = UserModel.objects.get(Q(email__iexact=username))
        except UserModel.DoesNotExist:
            # 避免密码枚举攻击,返回None前先哈希一个无效密码
            UserModel().set_password(password)
            return None
        except UserModel.MultipleObjectsReturned:
            user = UserModel.objects.filter(Q(email__iexact=username)).order_by("id").first()

        # 验证密码+用户状态
        if user.check_password(password) and user.is_staff and user.is_active:
            return user
        return None

3. 确认自定义用户模型(models.py)的正确性

关键要求:

  • 必须继承AbstractBaseUser和PermissionsMixin
  • 自定义管理器CustomUserManager正确实现create_user和create_superuser方法,确保超级用户的is_staff、is_active、is_superuser默认设为True
  • 明确指定USERNAME_FIELD = "email"

示例代码:

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

class CustomUserManager(BaseUserManager):
    def create_user(self, email, password=None, **extra_fields):
        if not email:
            raise ValueError("邮箱不能为空")
        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)
        extra_fields.setdefault("is_active", True)

        if extra_fields.get("is_staff") is not True:
            raise ValueError("超级用户必须设置is_staff=True")
        if extra_fields.get("is_superuser") is not True:
            raise ValueError("超级用户必须设置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)

    objects = CustomUserManager()

    USERNAME_FIELD = "email"
    REQUIRED_FIELDS = []  # 若需其他必填字段,在此添加

    def __str__(self):
        return self.email

4. 验证Admin.py配置

确保正确注册自定义用户模型,并指定登录字段为邮箱:

# admin.py
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import CustomUser

class CustomUserAdmin(UserAdmin):
    model = CustomUser
    list_display = ("email", "is_staff", "is_active")
    list_filter = ("email", "is_staff", "is_active")
    fieldsets = (
        (None, {"fields": ("email", "password")}),
        ("权限设置", {"fields": ("is_staff", "is_active", "is_superuser", "groups", "user_permissions")}),
        ("重要日期", {"fields": ("last_login", "date_joined")}),
    )
    add_fieldsets = (
        (None, {
            "classes": ("wide",),
            "fields": ("email", "password1", "password2", "is_staff", "is_active")}
        ),
    )
    search_fields = ("email",)
    ordering = ("email",)
    username_field = "email"  # 关键:指定Admin登录使用的字段

admin.site.register(CustomUser, CustomUserAdmin)

5. 手动验证用户状态

通过Django Shell确认超级用户的状态和密码有效性:

python manage.py shell
from your_app_name.models import CustomUser
# 替换为你的超级用户邮箱
user = CustomUser.objects.get(email="your_superuser_email@example.com")
print(f"is_staff: {user.is_staff}, is_active: {user.is_active}")
print(f"密码验证结果: {user.check_password('your_superuser_password')}")
  • 如果is_staff或is_active为False,直接修改为True并保存:user.is_staff = True; user.is_active = True; user.save()
  • 如果check_password返回False,说明密码未正确哈希,重新设置密码:user.set_password("new_password"); user.save()

6. 其他排查点

  • 清除浏览器缓存或使用隐私窗口登录,避免旧Session干扰
  • 若本地开发,确保settings.py中SESSION_COOKIE_SECURE和CSRF_COOKIE_SECURE设为False
  • 确认没有其他中间件拦截认证请求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 00:05:32