2016-07-19 54 views
0

创建谟,那么一个应用程序,并添加此应用到我的INSTALLED_APPS后,我试图在继承AbstractUser做出一个自定义的用户类我models.py为什么修改AUTH_USER_MODEL似乎需要子类AbstractUser?

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解决它。我不明白为什么看起来我的CustomUserauth.User之间有冲突。

回答

1

您的自定义用户模型继承AbstractUser这是一个模型类django.contrib.auth

AbstractUser本身从AbstractBaseUserPermissionsMixin模型定义并因此与经由PermissionsMixin类集团和权限模型相关

PermissionsMixin限定ManyToManyField关系PermissionGroups(这是另一个相关多对多与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"PermissionGroup模型,因此AbstractUser模型与这些模型具有反向关系。

当你继承了AbstractUser,你定义了具有相同related_nameGroupPermission反向关系的两个车型。

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

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

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

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

1

由于AbstractUser(或者说它继承的PermissionMixin)定义了与其他模型(即组,权限)的关系,并且它使用硬编码的related_name属性user_set以避免模型被换出时的混淆。

只要该类仍然是抽象类,这很好,但只要定义了具体的子类,Django就会定义与该模型的反向关系;现在您有两个模型使用相同的值user_set作为组的相关名称。

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

相关问题