为什么修改 AUTH_USER_MODEL 似乎需要子类 AbstractUser?

vmo*_*eco 1 django django-custom-user django-migrations

创建项目、应用程序并将该应用程序添加到我的 后INSTALLED_APPS,我尝试通过AbstractUser在我的 中进行子类化来创建自定义用户类models.py

from django.contrib.auth.models import AbstractUser

class CustomUser(AbstractUser):
    pass
Run Code Online (Sandbox Code Playgroud)

然后我尝试运行makemigrations并收到此错误:

SystemCheckError: System check identified some issues:

ERRORS:
auth.User.groups: (fields.E304) Reverse accessor for 'User.groups' clashes with reverse accessor for 'CustomUser.groups'.
    HINT: Add or change a related_name argument to the definition for 'User.groups' or 'CustomUser.groups'.
auth.User.user_permissions: (fields.E304) Reverse accessor for 'User.user_permissions' clashes with reverse accessor for 'CustomUser.user_permissions'.
    HINT: Add or change a related_name argument to the definition for 'User.user_permissions' or 'CustomUser.user_permissions'.
main.CustomUser.groups: (fields.E304) Reverse accessor for 'CustomUser.groups' clashes with reverse accessor for 'User.groups'.
    HINT: Add or change a related_name argument to the definition for 'CustomUser.groups' or 'User.groups'.
main.CustomUser.user_permissions: (fields.E304) Reverse accessor for 'CustomUser.user_permissions' clashes with reverse accessor for 'User.user_permissions'.
    HINT: Add or change a related_name argument to the definition for 'CustomUser.user_permissions' or 'User.user_permissions'.
Run Code Online (Sandbox Code Playgroud)

添加AUTH_USER_MODEL = 'main.CustomUser'main是我的应用程序)似乎可以解决这个问题(makemigrations成功,就像migrate),但我不明白为什么我会收到此错误,即使我只是定义了这个子类而没有实际使用它

我想首先了解为什么会出现这个问题,以及添加如何AUTH_USER_MODEL解决它。CustomUser我真的不明白为什么我和我之间看起来有冲突auth.User

kap*_*sdv 5

您的自定义用户模型继承AbstractUserdjango.contrib.auth.

AbstractUserAbstractBaseUser从和模型定义自身PermissionsMixin,因此通过 PermissionsMixin 类与 Group 和 Permission 模型相关

PermissionsMixin定义了与和(与 ManyToMany 进一步相关)模型的ManyToManyField关系,例如:PermissionGroupsPermission

class PermissionsMixin(models.Model):
....

    groups = models.ManyToManyField(
        Group,
        ....
        related_name="user_set",
        related_query_name="user",
    )
    user_permissions = models.ManyToManyField(
        Permission,
        ....
        related_name="user_set",
        related_query_name="user",
    )
Run Code Online (Sandbox Code Playgroud)

PermissionsMixin定义related_name="user_set"PermissionGroup模型,因此AbstractUser模型与这些模型具有反向关系。

当您子类化 时,您定义了两个与和AbstractUser具有相反关系的模型。GroupPermissionrelated_name

但是您不能有两个通用或外键具有相同的 related_names 指向同一模型。

您必须始终为字段指定唯一的反向名称和查询名称。这通常会在抽象基类中引起问题,因为该类上的字段包含在每个子类中,并且属性值完全相同。

因此,您的应用程序中只能有一个 a 的子类AbstractUser

如果您进行子类化AbstractUser,则必须将该子模型指向 AUTH_USER_MODEL,以便您的应用程序恰好指向 AbstractUser 的一个实例,而不是两个。