9

尝试创建我的自定义用户模型,这是我的代码:

模型.py

class CustomUser(AbstractUser):
    USERNAME_FIELD = 'email'

CustomUser._meta.get_field_by_name('email')[0]._unique=True

设置.py

AUTH_USER_MODEL = 'myapp.CustomUser'

在做manage.py syncdb时,出现如下错误:

CommandError: One or more models did not validate:
myapp.customuser: The field named as the USERNAME_FIELD should not be included in REQUIRED_FIELDS on a swappable User model.

任何人都可以解释一下吗?有没有更好的方法来自定义 Django 1.6 中的用户模型,而无需重写扩展 AbstractBaseUser 的整个类?

顺便说一句,如果我从我的代码中删除 USERNAME_FIELD = 'email' 并更改核心 django auth/models.py >> AbstractUser 定义,它就可以工作。我似乎无法覆盖 USERNAME_FIELD ...

谢谢!

4

3 回答 3

12

正如错误消息所表明的那样,原因是AbstractUser定义REQUIRED_FIELDS = ['email']. 而且您不能将 中的字段设置REQUIRED_FIELDS为您的USERNAME_FIELD. 更多细节在这里

因此,如果您想email作为主要字段,前进的方法是扩展和重新定义字段emailonAbstractBaseUser而不是 on AbstractUser

如果我没有完全掌握您的要求,这个问题/答案对可能与您相关。

于 2013-09-17T15:26:35.280 回答
6

Josvic,您的解决方案部分解决了我的问题。我最后要做的是:

class CustomUser(AbstractUser):

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['username']

    def get_username(self):
        return self.email

CustomUser._meta.get_field_by_name('email')[0]._unique=True

这解决了 REQUIRED_FIELDS 不能包含 USERNAME_FIELD 的初始问题,并且由于我不想重新定义整个用户并扩展 AbstractBaseUser,我必须在 REQUIRED_FIELD 中包含“用户名”,否则 syncdb 由于不同的原因而失败(预计用户名,以便将其保存到数据库中):

self.UserModel._default_manager.db_manager(database).create_superuser(**user_data)
TypeError: create_superuser() takes exactly 4 arguments (3 given)

因此,当第一次执行 syncdb 并且必须输入超级用户时,必须输入两次电子邮件,作为电子邮件和用户名。这很尴尬,但这是我能忍受的最干净的一个。

干杯!

于 2013-09-17T15:41:44.733 回答
2

Josvic 一针见血,但我想提供我使用的解决方案。这很简单。

  1. 删除“电子邮件”或您使用的任何内容USERNAME_FIELD来自REQUIRE_FIELDS.

  2. 在您创建的 UserManager 中,只需编写:

    如果不是电子邮件: raise ValueError('用户必须有一个电子邮件地址')

这样,您将手动强制要求电子邮件。

此解决方案是此处使用的解决方案:https ://docs.djangoproject.com/en/1.7/topics/auth/customizing/#a-full-example

于 2015-01-18T19:33:22.190 回答