1

在创建一个项目,然后是一个应用程序并将这个应用程序添加到我的INSTALLED_APPS之后,我尝试通过AbstractUser在我的子类中创建一个自定义用户类models.py

from django.contrib.auth.models import AbstractUser

class CustomUser(AbstractUser):
    pass

然后我尝试运行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'.

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

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

4

2 回答 2

4

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

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

PermissionsMixin定义与和的ManyToManyField关系(这与 ManyToMany 进一步相关)模型,例如: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",
    )

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

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

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

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

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

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

于 2016-07-19T16:34:25.610 回答
1

因为 AbstractUser(或者更确切地说是它继承的 PermissionMixin)定义了与那些其他模型的关系——即组、权限——并且它使用硬编码的 related_name 属性,user_set以避免在模型被换出时造成混淆。

只要类保持抽象就可以了,但是一旦定义了具体的子类,Django 就会定义与该模型的反向关系;现在您有两个模型使用相同的值,user_set作为 Group 中的相关名称。

如果你设置了 AUTH_USER_MODEL,那么 Django 就不再定义标准的 User 类;所以你又回到了只有一个类使用该相关名称的情况。

于 2016-07-19T16:04:47.573 回答