【问题标题】:Django custom user model and usermanagerDjango 自定义用户模型和用户管理器
【发布时间】:2013-05-12 11:03:19
【问题描述】:

我正在使用 Django 1.5 构建一个 Web 应用程序。我正在使用带有自定义 UserManager 的自定义用户模型。 我遵循了官方 Django 文档的说明和示例。

现在,当我尝试通过UserManager.create_user(...) 创建新用户时,我收到了 NoneType 错误:看来 UserManager 的属性模型是 None 类型。 我想我在 User 模型中正确设置了 UserManager (objects = UserManager())

我真的不知道我在哪里犯了错误。 Booth 我的编码伙伴和我是 Django 的新手。也许你可以帮助我们。

代码如下:

class UserManager(BaseUserManager):
"""
    create a new user

    @param username:  the name for the new user
    @param password:  the password for the new user. if none is provided a random password is generated
    @param person:    the corresponding person object for this user
"""
def create_user(self, username, person, password=None):
    if not username:
        raise ValueError('User must have a valid username')

    user = self.model(username=username, created=datetime.now(), must_change_password=True, deleted=False, person=person)

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

class User(AbstractBaseUser):
    ## the id of the user. unique through the application
    user_id     =   models.AutoField(primary_key=True)
    ## the name of the user. unique through the application
    username    =   models.CharField(max_length=32, unique=True)
    ## the date when the user was created
    created     =   models.DateTimeField()
    ## iff this is true the user must set a new password at next login
    must_change_password    =   models.BooleanField(default=True)
    ## iff true the user is marked as deleted and can not login
    deleted     =   models.BooleanField(default=False)
    ## iff true the user is admin and has all permissions. use with care!
    is_admin = models.BooleanField(default=False)
    ## reference to the person entity that is linked to this specific user
    person      =   models.ForeignKey(Person)
    ## indicates if the user is active or not
    active    =    models.BooleanField(default=True)

    ## define the user manager class for User
    objects     =   UserManager()

    # necessary to use the django authentication framework: this field is used as username
    USERNAME_FIELD  =   'username'

我在 UserManager 的 create_user() 方法中的 user = self.model(..) 行收到 NoneType 错误

【问题讨论】:

    标签: python django django-models django-users


    【解决方案1】:

    要创建新用户,您不应调用UserManager.create_user(...)。相反,您应该使用:

    from django.contrib.auth import get_user_model
    get_user_model().objects.create_user(...)
    

    这就是 django 管理器的工作方式。你可以阅读文档here

    【讨论】:

      【解决方案2】:

      我在保存自定义用户模型时也遇到了问题,我花了一段时间才弄清楚

      我认为您的代码中的重要行是:

      objects     =   UserManager()
      

      在 User 类中,因此为了保存新用户,您需要调用

      new_user=User.objects.create_user(args, args, args, etc)
      

      objects”是调用UserManager类的项目,在django中被称为经理

      【讨论】:

      • 请解释为什么这个方法不好谁不赞成答案。
      【解决方案3】:

      我不得不添加一个答案,因为我没有足够的代表发表评论。但是@Aldarund 的答案中的链接根本没有描述 get_user_model() 的使用。但是,this link 应该会有所帮助...

      【讨论】:

        【解决方案4】:

        更新解决方案的重要警告... 如果您遇到此类问题,您可能已经尝试了网络上的各种解决方案,告诉您将 AUTH_USER_MODEL = users.CustomUser 添加到 settings.py,然后将以下代码添加到 views.py forms.py 和任何其他文件致电User:

        from django.contrib.auth import get_user_model
        User = get_user_model()
        

        然后当你得到错误时你会挠头:

        Manager isn't available; 'auth.User' has been swapped for 'users.User'
        

        任何时候您的代码引用User,例如:

        User.objects.get()
        

        因为您知道您已经将 objects = UserManager() 放入自定义用户类中(UserManager 是扩展 BaseUserManager 的自定义管理器的名称)。

        事实证明(感谢@Aldarund)正在做:

        User = get_user_model() # somewhere at the top of your .py file
        # followed by
        User.objects.get() # in a function/method of that same file
        

        不等于:

        get_user_model().objects.get() # without the need for User = get_user_model() anywhere
        

        也许不直观,但事实证明,在 python 中,在导入时执行一次 User = get_user_model() 不会导致在后续调用中定义 User(即它不会将 User 变成如果您来自 C/C++ 背景,您可能会期望这种“常量”;这意味着 User = get_user_model() 的执行发生在导入时,但随后在随后调用类或函数之前被取消引用/该文件中的方法)。

        综上所述,在所有引用User类的文件中(例如调用函数或变量如User.objects.get()User.objects.all()User.DoesNotExist等...):

        # Add the following import line
        from django.contrib.auth import get_user_model
        
        # Replace all references to User with get_user_model() such as...
        user = get_user_model().objects.get(pk=uid)
        # instead of  user = User.objects.get(pk=uid)
        # or
        queryset = get_user_model().objects.all()
        # instead of queryset = User.objects.all()
        # etc...
        

        希望这可以帮助其他人节省一些时间...

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-12-13
          • 2013-06-01
          • 2011-05-03
          • 2021-12-01
          • 2014-09-03
          • 1970-01-01
          • 2023-03-26
          相关资源
          最近更新 更多