在 Django 用户模型中独一无二
Posted
技术标签:
【中文标题】在 Django 用户模型中独一无二【英文标题】:Unique together in Django User Model 【发布时间】:2018-08-30 11:27:29 【问题描述】:我想更新 Django User 表,并在其中添加另一个字段。我就是这样做的。
class User(AbstractUser):
platform = models.CharField(max_length=10)
USERNAME_FIELD = 'email'
现在,因为有一个字段 USERNAME_FIELD
需要一个唯一字段。但是,我希望 username and platform
应该是 unique_together
,而不仅仅是 username
。
我怎样才能做到这一点?
【问题讨论】:
请看docs.djangoproject.com/en/2.0/ref/models/options/… 我知道这个元字段。但是,我怀疑这会起作用,因为继承AbstractUser
模型需要一个应该是唯一的 USERNAME_FIELD
。并且 Django User 模型也遵循User
模型中的一个字段应该是唯一的原则。
【参考方案1】:
AbstractUser 是一个基本完整的模型,它定义了一组默认字段,包括用户名的唯一性。如果这对您不起作用,那么您应该从 AbstractBaseUser 继承并定义完整的字段集。
【讨论】:
即使AbstractBaseUser
也有一个独特的字段USERNAME_FIELD
。我宁愿有 2 个字段为 unique_together
。
有什么线索吗?
不,它没有。它根本没有定义用户名字段,也没有施加任何约束。
AttributeError: type object 'User' has no attribute 'USERNAME_FIELD'
这是我得到的错误。基本上,它在内部检查if cls.USERNAME_FIELD in cls.REQUIRED_FIELDS
,因此会出错。【参考方案2】:
用户名字段的唯一性仅在您使用内置身份验证后端时。
直接来自 django 文档
如果您使用默认身份验证后端,那么您的模型必须有一个唯一字段...如果您使用可以支持的自定义身份验证后端,则允许使用非唯一用户名字段。
Django Custom Authentication
希望对你有帮助
【讨论】:
【参考方案3】:从您的问题和 cmets 非常清楚(如果我没有完全误解的话)您想要保存具有多个 email
(标识符)和多个 platform
的用户。如果是这种情况,如果您的数据库是 Postgresql,您可以在 platform
列上使用 postgres ArrayField
,或者您也可以使用 django 提供的 JsonField
。
Postgresql Array Field 在 django > 1.7 中可用
Django Json Field
【讨论】:
【参考方案4】:我可能来不及回答这个问题,但我最近针对同一问题使用的解决方案是:
class User(AbstractUser):
platform_and_email = models.CharField(max_length=100, unique=True)
username = models.CharField(max_length=20, blank=True, null=True)
email = models.EmailField(_('email address'), unique=True)
USERNAME_FIELD = 'platform_and_email'
REQUIRED_FIELDS = ['username', 'first_name', 'last_name']
class Meta:
verbose_name = "App User"
verbose_name_plural = "App Users"
您可以使用单个字段并将其设置为唯一。在您的应用程序的客户端,您可以通过在后台执行“平台_”+电子邮件来验证用户身份。
您还必须编写自己的自定义后端,并使其使用您的 platform_and_email 字段进行验证和身份验证。
如果您需要更多解释,请告诉我。
【讨论】:
以上是关于在 Django 用户模型中独一无二的主要内容,如果未能解决你的问题,请参考以下文章
在 Django 中扩展用户对象:用户模型继承还是使用 UserProfile?