首页 文章

Django 1.6 AbstractUser不工作

提问于
浏览
5

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

models.py

class CustomUser(AbstractUser):
    USERNAME_FIELD = 'email'

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

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

谢谢!

3 回答

  • 5

    正如错误消息所明确的那样,原因是 AbstractUser 定义了 REQUIRED_FIELDS = ['email'] . 并且您无法在 REQUIRED_FIELDS 中将字段设置为 USERNAME_FIELD . 更多细节here .

    因此,如果您希望 email 作为主要字段,那么前进的方法是在 AbstractBaseUser 上扩展并重新定义字段 email 而不是 AbstractUser .

    如果我没有完全掌握你的要求,这个question/answer pair可能与你有关 .

  • 1

    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的初始问题,因为我不想重新定义整个User并扩展AbstractBaseUser,我必须在REQUIRED_FIELD中包含'username',否则syncdb会因为其他原因而失败(期待用户名,以便将其保存到数据库中):

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

    因此,当第一次执行syncdb并且必须输入超级用户时,必须输入两次电子邮件,如电子邮件和用户名 . 它很尴尬,但它是最干净的,我可以忍受它 .

    干杯!

  • 3

    Josvic撞到了头上,但我想提供我用过的解决方案 . 这很简单 .

    • REQUIRE_FIELDS 删除'email'或您正在使用的任何内容 USERNAME_FIELD .

    • 在您创建的UserManager中,只需写:

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

    这样,您将手动强制要求发送电子邮件 .

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

相关问题