我想使用电子邮件字段作为自定义用户模型的用户名字段。 我有以下自定义用户模型子类化Django的AbstractUser模型:
class CustomUser(AbstractUser):
....
email = models.EmailField(max_length=255, unique=True)
USERNAME_FIELD = 'email'
但是当我跑步时
python manage.py sql myapp
我收到以下错误:
FieldError:“CustomUser”类中的本地字段“email”与基类“AbstractUser”中类似名称的字段发生冲突
我首先添加自己的电子邮件字段的原因是为其添加unique=True
选项。否则我得到:
myapp.customuser:USERNAME_FIELD必须是唯一的。将unique = True添加到字段参数中。
现在,就此而言:
https://docs.djangoproject.com/en/1.5/topics/db/models/#field-name-hiding-is-not-permitted
可以如何实现这一目标? (另外,然后命名字段“user_email”或类似的东西)
答案 0 :(得分:37)
伊恩,非常感谢你的聪明回应:)
但是,我已经“修补”了我的解决方案。
由于AbstractUser
也有一个username
字段,对我来说完全没必要
我决定创建“自己的”AbstractUser
。
通过继承AbstractBaseUser
和PermissionsMixin
,我保留了大多数用户模型内置方法,而不添加任何代码。
我还利用这个机会创建了一个自定义Manager
来消除username
字段中的使用:
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager
class CustomUser(AbstractBaseUser, PermissionsMixin):
....
email = models.EmailField(max_length=255, unique=True)
first_name = ...
last_name = ...
is_active = ...
is_staff = ...
....
objects = CustomUserManager()
USERNAME_FIELD = 'email'
class CustomUserManager(BaseUserManager):
def create_user(self, email, password=None, **extra_fields):
.....
def create_superuser(self, email, password, **extra_fields):
.....
这个解决方案确实导致重复一些Django的内置代码(主要是AbstractUser
中已经存在的模型字段,例如'first_name','last_name'等),但也在一个更干净的User对象中数据库表。
真是遗憾的是1.5中引入USERNAME_FIELD
的灵活性不能用于实际在所有现有约束下创建灵活的用户模型。
编辑:官方文档中提供了一个全面的工作示例:https://docs.djangoproject.com/en/dev/topics/auth/customizing/#a-full-example
答案 1 :(得分:9)
如果您的真实目标是唯一的“电子邮件”值,并忽略“用户名”值,那么您可以:
sha256(user.email).hexdigest()[:30]
以这种方式添加唯一性:
class User(AbstractUser):
class Meta:
unique_together = ('email', )
这导致:
CREATE TABLE "myapp_user" (
...
"email" varchar(75) NOT NULL,
UNIQUE ("email")
)
按预期工作,非常简单。
答案 2 :(得分:7)
您可以修改CustomUser
,将email
字段属性更改为unique=True
。
将此添加到自定义用户类的末尾,如下所示:
class CustomUser(AbstractUser):
...
USERNAME_FIELD = 'email'
...
CustomUser._meta.get_field_by_name('email')[0]._unique=True
请注意,我们正在更改_unique
而不是unique
,因为后者是一个简单的@property
。
这是一个黑客攻击,我很想听到任何“官方”的答案来解决这个问题。
答案 3 :(得分:2)
使用官方网站上的示例:
https://docs.djangoproject.com/en/1.7/topics/auth/customizing/#a-full-example
以下是符合管理员的自定义用户应用的示例。此用户模型使用电子邮件地址作为用户名,并具有所需的出生日期;除了用户帐户上的简单管理标志之外,它不提供权限检查。除用户创建表单外,此模型将与所有内置身份验证表单和视图兼容。此示例说明了大多数组件如何协同工作,但不打算直接复制到项目中以供生产使用。