Django 1.6 AbstractUser 不工作

问题描述 投票:0回答:4

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

模型.py

class CustomUser(AbstractUser):
    USERNAME_FIELD = 'email'

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

设置.py

AUTH_USER_MODEL = 'myapp.CustomUser'

在执行manage.pysyncdb时,出现以下错误:

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...

谢谢!

django
4个回答
12
投票

正如错误消息所明确的,原因是

AbstractUser
定义了
REQUIRED_FIELDS = ['email']
。并且您无法将
REQUIRED_FIELDS
中的字段设置为您的
USERNAME_FIELD
。更多详情这里

因此,如果您希望

email
作为您的主要领域,前进的道路就是在
email
上扩展并重新定义领域
AbstractBaseUser
,而不是在
AbstractUser
上。

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


8
投票

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 中包含“用户名”,否则同步数据库会因其他原因而失败(预计用户名,以便将其保存到数据库中):

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

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

干杯!


2
投票

Josvic 说得很中肯,但我想提供我使用的解决方案。非常简单。

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

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

    如果没有电子邮件: raise ValueError('用户必须有电子邮件地址')

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

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


0
投票

使用 Django 5.0,makemigrations 使用以下内容为我工作:

class CustomUser(AbstractUser):

   # username field deleted and email field set as identifier field
   email = models.EmailField(unique=True)
   username = None
   REQUIRED_FIELDS = []
   USERNAME_FIELD = 'email'

   def get_username(self):
       return self.email

删除所有 REQUIRED_FIELDS 允许您将 USERNAME_FIELD 定义为“电子邮件”。重写 get_username 方法是一个好处。 希望这可以帮助那些遇到与我相同错误的人:“自定义用户模型的名为“USERNAME_FIELD”的字段不得包含在“REQUIRED_FIELDS”中。”。

© www.soinside.com 2019 - 2024. All rights reserved.