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

使用Django AbstractUser自定义用户模型时出现TypeError: all()缺少self参数

Django自定义用户模型报错:TypeError: all() missing 1 required positional argument: 'self'

问题重现

自定义用户模型代码:

class User(AbstractUser):
    nickname = models.CharField(max_length=32)
    birthday = models.DateField()
    objects = MyUserManager  # 问题核心所在
    class Meta:
        ordering = ('-id',)

自定义管理器代码:

class MyUserManager(UserManager):
    def _create_user(self, username, email, password, **kwargs):
        if not username:
            raise ValueError("The given username must be set")
        user = self.model(email=self.normalize_email(email), **kwargs)
        user.set_password(password)
        user.save()
        return user

    def create_user(self, username, email=None, password=None, **kwargs):
        kwargs.setdefault('is_admin', False)
        return self._create_user(username, email, password, **kwargs)

    def create_superuser(self, username, email=None, password=None, **kwargs):
        kwargs.setdefault("is_staff", True)
        kwargs.setdefault('is_admin', True)
        return self._create_user(username, email, password, **kwargs)

ViewSet代码:

class UserViewSet(ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializers

触发的错误:

TypeError: all() missing 1 required positional argument: 'self'

错误原因分析

1. 核心错误:模型管理器未实例化

你在User模型中把管理器类直接赋值给了objects,而不是管理器的实例。Django要求模型管理器必须是类的实例才能正常工作,当调用User.objects.all()时,相当于直接调用MyUserManager.all()——用类去调用实例方法,自然会缺少self参数(实例方法的第一个参数必须是类的实例本身)。

2. 原生User.objects是什么?

原生User.objects是django.contrib.auth.models.UserManager的实例,Django会自动为默认用户模型创建这个实例,所以调用all()等方法时,是通过实例调用,不会出现参数缺失问题。

3. MyUserManager的其他潜在问题

除了未实例化的问题,你的管理器还有几处需要修正:

  • _create_user中的user.save()应改为user.save(using=self._db),确保多数据库环境下使用正确的数据库连接;
  • create_user和create_superuser中使用了is_admin字段,但你的User模型并未定义该字段,AbstractUser默认用is_superuser标识超级用户,这里会导致创建用户时报错;
  • create_superuser缺少对is_superuser的设置,会导致创建的超级用户不具备完整权限。

解决方法

第一步:修正模型的管理器赋值

把objects = MyUserManager改为实例化形式:

class User(AbstractUser):
    nickname = models.CharField(max_length=32)
    birthday = models.DateField()
    objects = MyUserManager()  # 添加括号,实例化管理器
    class Meta:
        ordering = ('-id',)

第二步:修正MyUserManager的逻辑

class MyUserManager(UserManager):
    def _create_user(self, username, email, password, **kwargs):
        if not username:
            raise ValueError("The given username must be set")
        email = self.normalize_email(email)
        user = self.model(username=username, email=email, **kwargs)
        user.set_password(password)
        user.save(using=self._db)  # 添加数据库连接参数
        return user

    def create_user(self, username, email=None, password=None, **kwargs):
        # 改用AbstractUser默认字段,若需is_admin需先在模型中定义
        kwargs.setdefault('is_staff', False)
        kwargs.setdefault('is_superuser', False)
        return self._create_user(username, email, password, **kwargs)

    def create_superuser(self, username, email=None, password=None, **kwargs):
        kwargs.setdefault('is_staff', True)
        kwargs.setdefault('is_superuser', True)
        # 若需is_admin字段,先在User模型中添加后再启用下面一行
        # kwargs.setdefault('is_admin', True)

        # 校验超级用户必要字段
        if kwargs.get('is_staff') is not True:
            raise ValueError('Superuser must have is_staff=True.')
        if kwargs.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True.')

        return self._create_user(username, email, password, **kwargs)

第三步:同步数据库

修改完成后执行数据库迁移:

python manage.py makemigrations
python manage.py migrate

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 01:39:18