【问题标题】:Omitting password field for custom django user model省略自定义 django 用户模型的密码字段
【发布时间】:2019-08-01 18:15:33
【问题描述】:

我想拥有我自己的自定义 Django 用户模型,只有

email id、first_name、last_name 和 date_joined

fields。我不想有 password 列,因为身份验证是通过 Microsoft SAML 进行的,因此我不需要存储任何密码。我的用户模型如下:

from __future__ import unicode_literals
from django.db import models
from django.contrib.auth.models import PermissionsMixin, 
                                       BaseUserManager, AbstractBaseUser
from django.utils.translation import ugettext_lazy as _


class UserManager(BaseUserManager):
    def _create_user(self, email, **extra_fields):
        if not email:
            raise ValueError('The Email must be set')
        email = self.normalize_email(email)
        user = self.model(email=email, extra_fields)
        user.save()

        return user

    def create_superuser(self, email, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        extra_fields.setdefault('is_active', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError('Superuser must have is_staff=True.')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True.')
        return self._create_user(email, **extra_fields)


class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(_('email address'), unique=True)
    first_name = models.CharField(_('first name'), max_length=30, blank=True)
    last_name = models.CharField(_('last name'), max_length=30, blank=True)
    date_joined = models.DateTimeField(_('date joined'), auto_now_add=True)

    objects = UserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['first_name', 'last_name']

    class Meta:
        verbose_name = _('user')
        verbose_name_plural = _('users')

    def get_full_name(self):
        full_name = f'{self.first_name} {self.last_name}'
        return full_name.strip()

但是,当我运行迁移时,我也可以在用户表中看到密码字段。我做错了什么?

【问题讨论】:

  • AbstractBaseUser 有一个密码字段。如果您不覆盖它,它将作为一个字段包含在您的模型中。只需设置password = None 就可以了。但@kamalSingh 的回答可能是这样做的预期方式,因为它明确提到了外部身份验证系统。

标签: python django


【解决方案1】:

我无法发表评论,但您可以使用“set_unusable_password”来跳过密码字段。

https://docs.djangoproject.com/en/2.0/ref/contrib/auth/#django.contrib.auth.models.User.set_unusable_password

像这样:

class UserManager(BaseUserManager):
    def _create_user(self, email, **extra_fields):
        if not email:
            raise ValueError('The Email must be set')
        email = self.normalize_email(email)
        user = self.model(email=email, extra_fields)
        user.set_unusable_password()
        user.save()

        return user

【讨论】:

  • 这看起来很有希望..但是我如何合并它以便在系统上创建新用户时始终取消设置新用户的密码..
  • 对不起,你指的是什么系统?
  • 您可以覆盖您的用户保存方法来设置不可用的密码。
  • 在你的 UserManager _create_user 方法中你可以使用 user.set_unusable_password()
  • @KamalSingh 您应该将其添加到答案中。
【解决方案2】:

这是一个黑客。 您可以删除此字段 ('password', models.CharField(max_length=128, verbose_name='password')), 从迁移文件。但是,这是不可扩展的。

【讨论】:

    【解决方案3】:

    我设法使用以下代码删除了用户密码字段。

    class UserManager(BaseUserManager):
    def _create_user(self, email, **extra_fields):
        if not email:
            raise ValueError('The Email must be set')
        email = self.normalize_email(email)
        user = self.model(email=email, extra_fields)
        user.set_unusable_password()
        user.save()
    
        return user
    

    在你的用户模型类中:

    class User(AbstractBaseUser, PermissionsMixin):
      email = models.EmailField(_('email address'), unique=True)
      first_name = models.CharField(_('first name'), max_length=30, blank=True)
      last_name = models.CharField(_('last name'), max_length=30, blank=True)
      date_joined = models.DateTimeField(_('date joined'), auto_now_add=True)
      password = None
    
      objects = UserManager()
      ...
    

    当然,然后运行

    python manage.py makemigrations
    

    然后

    python manage.py migrate
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-28
      • 2021-04-15
      • 2022-12-12
      • 1970-01-01
      • 1970-01-01
      • 2020-10-26
      • 2017-01-10
      • 2016-04-27
      相关资源
      最近更新 更多