创建专业版,然后是应用并将此应用添加到我的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
之间存在冲突。
答案 0 :(得分:2)
您的自定义用户模型会继承AbstractUser
,这是django.contrib.auth
的模型类。
AbstractUser
从AbstractBaseUser
和PermissionsMixin
模型定义自己,因此通过PermissionsMixin类与组和权限模型相关
PermissionsMixin
定义与ManyToManyField
和Permission
的{{1}}关系(与Groups
进一步相关的ManyToMany)模型如下:
Permission
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",
)
使用PermissionsMixin
和related_name="user_set"
模型定义Permission
,因此Group
模型与这些模型具有反向关系。
当您继承AbstractUser
时,您定义了两个与AbstractUser
和Group
具有相反关系且与Permission
具有相反关系的模型。
但是你不能有两个具有相同related_names的通用或外键指向同一个模型。
您必须始终为该字段指定唯一的反向名称和查询名称。这通常会导致抽象基类出现问题,因为此类中的字段包含在每个子类中,并且属性的值完全相同。
因此,您的应用程序中只能有一个related_name
的子类。
如果您继承AbstractUser
,那么您必须将该子模型指向AUTH_USER_MODEL,以便您的应用程序仅指向AbstractUser的一个实例,而不是两个。
答案 1 :(得分:1)
因为AbstractUser(或者它继承自的PermissionMixin)定义了与其他模型的关系 - 即组,权限 - 并且它使用硬编码的related_name属性user_set
,以避免在模型是换掉了。
只要该类保持抽象,那就没问题了,但只要定义了一个具体的子类,Django就会定义与该模型的反向关系;现在,您有两个使用相同值user_set
的模型作为Group中的相关名称。
如果设置AUTH_USER_MODEL,则Django不再定义标准User类;所以你回到只有一个类使用那个相关名称的情况。