【问题标题】:Cannot create super user in django无法在 django 中创建超级用户
【发布时间】:2016-11-03 07:35:32
【问题描述】:

我知道 SO 中有关于此问题的问题。但大多数问题都与AbstractBaseUser 有关。我没有找到AbstractUser 的任何问题。

问题:

我想为 django 项目实现身份验证。所以我想通过继承AbstractUser来实现自定义用户模型。

这是我的模型:

class User(AbstractUser):

   phonenumber = models.CharField(max_length=25,unique=True)
   username = models.CharField(max_length=25,default="")
   profile_path = models.URLField(max_length=1500)
   country = models.CharField(max_length=100,default="")
   what_do_you_do = models.CharField(max_length=500,default="")
   where_do_you_do = models.CharField(max_length=500,default="")
   time_stamp = models.DateTimeField(auto_now_add=True,blank=True)


   USERNAME_FIELD = 'phonenumber'

我在 settings.py 中添加了AUTH_USER_MODEL = 'XXX.User'。我想创建一个超级用户。

   python manage.py createsuperuser

但它给了我以下错误:

Traceback (most recent call last):
File "manage.py", line 22, in <module>
execute_from_command_line(sys.argv)
File "/home/sandesh/server/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 367, in execute_from_command_line
utility.execute()
File "/home/sandesh/server/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 359, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/sandesh/server/local/lib/python2.7/site-packages/django/core/management/base.py", line 294, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/sandesh/server/local/lib/python2.7/site-packages/django/contrib/auth/management/commands/createsuperuser.py", line 63, in execute
return super(Command, self).execute(*args, **options)
File "/home/sandesh/server/local/lib/python2.7/site-packages/django/core/management/base.py", line 345, in execute
output = self.handle(*args, **options)
File "/home/sandesh/server/local/lib/python2.7/site-packages/django/contrib/auth/management/commands/createsuperuser.py", line 183, in handle
   self.UserModel._default_manager.db_manager(database).create_superuser(**user_data)
TypeError: create_superuser() takes exactly 4 arguments (3 given)

【问题讨论】:

  • 只是确保 - 您是否应用了迁移?
  • 是的。我做到了。我没有实现 UserManager。这个错误与@ApoorvKansal 有什么关系
  • 您使用的是哪个版本的 Djagno?如果 >=1.8,您需要将 PermissionsMixin 传递给您的 User 类
  • 您应该创建自己的用户管理器。

标签: python django django-models django-rest-framework


【解决方案1】:
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager



class MyUserManager(BaseUserManager):
    def create_user(self, phonenumber, password=None):
        if not phonenumber:
            raise ValueError('Users must have an phonenumber')

        user = self.model(
            phonenumber=phonenumber,
        )

        user.save(using=self._db)
        return user

    def create_superuser(self, phonenumber, password=None):
        user = self.model(
            phonenumber=phonenumber
        )
        user.is_admin = True
        print(password)
        user.set_password(password)
        user.save(using=self._db)
        return user


class User(AbstractBaseUser):

   phonenumber = models.CharField(max_length=25,unique=True)
   user= models.CharField(max_length=25,default="")
   profile_path = models.URLField(max_length=1500)
   country = models.CharField(max_length=100,default="")
   what_do_you_do = models.CharField(max_length=500,default="")
   where_do_you_do = models.CharField(max_length=500,default="")
   time_stamp = models.DateTimeField(auto_now_add=True,blank=True)
   is_admin = models.BooleanField(default=False)
   def has_perm(self, perm, obj=None):
    return self.is_admin
   def has_module_perms(self, app_label):
    return self.is_admin

   objects = MyUserManager()
   USERNAME_FIELD = 'phonenumber'

   @property
   def is_staff(self):
    return self.is_admin

   def get_short_name():
    return self.phonenumber

根据 Django 文档:

您还应该为您的用户模型定义一个自定义管理器。如果你的 User 模型定义了与 Django 的默认用户相同的 username、email、is_staff、is_active、is_superuser、last_login 和 date_joined 字段,你可以只安装 Django 的 UserManager;但是,如果您的 User 模型定义了不同的字段,您将需要定义一个扩展 BaseUserManager 的自定义管理器,提供两个附加方法:create_user()create_superuser()

因此,我为您提供了一个自定义管理器。保持正常设置。注意:如您的模型中所示,您没有 password 字段,因此我假设在这种情况下您不需要一个。

也从AbstractBaseUser 扩展,而不是AbstractUser

【讨论】:

  • 谢谢@Apoorv,我已经创建成功了。我创建了超级用户。但无法登录管理员。它说Please enter the correct phonenumber and password for a staff account. Note that both fields may be case-sensitive. 是否需要对 MyUserManager 中的密码字段做任何事情?
  • 更新了代码以支持密码输入。请查看更改。我能够成功登录到管理中心。
  • 这很有帮助 非常感谢。现在我可以申请 oath2 认证了吧?
  • 如果您对 OAuth 1.0/2.0 有疑问,请考虑提出另一个问题。至于现在,我建议使用requests-oauthlib.readthedocs.io/en/latest
【解决方案2】:

问题在于您创建的用户模型。

    class User(AbstractUser):

       phonenumber = models.CharField(max_length=25,unique=True)
       username = models.CharField(max_length=25,default="")
       profile_path = models.URLField(max_length=1500)
       country = models.CharField(max_length=100,default="")
       what_do_you_do = models.CharField(max_length=500,default="")
       where_do_you_do = models.CharField(max_length=500,default="")
       time_stamp = models.DateTimeField(auto_now_add=True,blank=True)


       REQUIRED_FIELDS = ['username']

在您的模型中添加 REQUIRED_FIELDS。

还有一件事,如果你喜欢 Django 的用户模型字段的方式,应该使用抽象用户,但需要额外的字段。所以这意味着,如果你想使用抽象用户,那么你应该在用户模型中添加新的字段并且不重写 Django auth 用户模型的预定义字段。因此,您需要删除 Django 用户模型中已经存在的所有字段,或者将 AbstractBaseUser 用于全新的用户模型。

进一步阅读Here

【讨论】:

  • 我已经添加了REQUIRED_FIELDS = ['username'],但它仍然给我同样的错误。
  • @Naroju 阅读整个答案。您需要删除 USERNAME_FIELD = 'phonenumber' 或者如果您想根据 phonenumber 自定义 User 模型,您应该使用 AbstractBaseUser 而不是 AbstractUser。 AbstractUser 本身是 Django 用户模型的扩展。您不能覆盖其中已有的字段。您可以在 AbstractUser 中添加更多字段。
【解决方案3】:

您可以像这样实现自定义用户模型-:

from django.contrib.auth.models import AbstractBaseUser, UserManager
from django.contrib.auth.models import PermissionsMixin

class User(AbstractBaseUser, PermissionsMixin):
 '''

 '''

  username = models.CharField(max_length=50, null=True)
  first_name =models.CharField(max_length=50, null=True)
  last_name = models.CharField(max_length=50, null=True)
  email = models.EmailField(unique=True)
  is_active = models.BooleanField(default=True)
  is_staff = models.BooleanField(default=False)  
  date_joined = models.DateTimeField(default=timezone.now)

  USERNAME_FIELD = 'email'
  REQUIRED_FIELDS = ['username', ]
  objects = UserManager()

【讨论】:

  • 我使用的是 django 1.10 版本。我使用的是AbstractUser 而不是AbstractBaseUser。但是它不需要用户管理器实现吗?
  • @Naroju ,现在您正在使用 AbstractBaseUser 并且您也需要 UserManager。
猜你喜欢
  • 1970-01-01
  • 2012-12-13
  • 2023-03-13
  • 2017-06-27
  • 2021-08-19
  • 1970-01-01
  • 2015-12-08
  • 2021-07-31
  • 2017-11-11
相关资源
最近更新 更多