【问题标题】:Why is custom user password not getting set and authenticated?为什么没有设置和验证自定义用户密码?
【发布时间】:2021-06-30 00:15:20
【问题描述】:

我认为将 User 模型的用户名与其电子邮件交换是轻而易举的事。所以我使用的是CustomUser

from django.contrib.auth.models import AbstractUser
from django.db import models
from django.utils.translation import ugettext_lazy as _
from .managers import UserManager

class CustomUser(AbstractUser):
    """User model."""

    username = None
    email = models.EmailField(_('email address'), unique=True)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    objects = UserManager()

由于CustomUser继承自AbstractUser模型,我以为我已经完成了,但我想我离它还很远。

这是我的 django shell 交互:

>> from django.contrib.auth import get_user_model
>> User = get_user_model()
>> User.objects.create(email='dave@gmail.com', password='123')                                                                                                                                        
   <CustomUser: dave@gmail.com> 
>> User.objects.get(email='dave@gmail.com').password
   '123' # wutt? why is this plaintext?
>> User.objects.get(email='dave@gmail.com').set_password('abc')
>> User.objects.get(email='dave@gmail.com').password
   '123' # still same!

所以在功能上,这完全没用。因为用户的django.contrib.auth.authenticate 总是返回None。我究竟做错了什么?如何实现我的CustomUser 与默认 django 用户模型仅不同之处在于我的CustomUser 应该使用电子邮件作为用户名的最小功能?

我已经查看了 SO 点击数:

Django User password not getting hashed for custom users

django custom user model password is not being hashed

编辑:我使用以下内容作为我的UserManager

from django.contrib.auth.models import BaseUserManager

class UserManager(BaseUserManager):
    """Define a model manager for User model with no username field."""

    use_in_migrations = True

    def _create_user(self, email, password, **extra_fields):
        """Create and save a User with the given email and password."""
        if not email:
            raise ValueError('The given email must be set')
        email = self.normalize_email(email)
        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_user(self, email, password=None, **extra_fields):
        """Create and save a regular User with the given email and password."""
        extra_fields.setdefault('is_staff', False)
        extra_fields.setdefault('is_superuser', False)
        return self._create_user(email, password, **extra_fields)

    def create_superuser(self, email, password, **extra_fields):
        """Create and save a SuperUser with the given email and password."""
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', 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, password, **extra_fields)

【问题讨论】:

  • 如何注册/创建用户?同样set_password 不会保存用户,所以User.objects.get(email='dave@gmail.com').set_password('abc') 自然不会改变任何东西。尝试类似user = User.objects.get(email='dave@gmail.com') 然后user.set_password('abc') 然后user.save()

标签: python django


【解决方案1】:

您使用User.objects.create(email='dave@gmail.com', password='123') 创建您的用户。 .create() 不考虑密码需要散列(这是所有型号提供的常规方法)。而是使用.create_user():

User.objects.create_user(email='dave@gmail.com', password='123')

您也尝试通过以下方式设置用户密码:

User.objects.get(email='dave@gmail.com').set_password('abc')

这不起作用,因为set_password 不会将任何内容保存到数据库中。你应该这样做:

user = User.objects.get(email='dave@gmail.com')
user.set_password('abc')
user.save()

【讨论】:

  • 嗯不知道为什么我会得到create_user() missing 1 required positional argument: 'username'
  • @DaveIdito 你设置AUTH_USER_MODEL = 'yourapp.CustomUser了吗?
  • 对不起,我的错。这是正确的答案。我正在调试,结果我的objects = UserMa... 行受到了赞扬。现在一切正常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-30
  • 1970-01-01
  • 2011-09-15
  • 2011-10-23
  • 1970-01-01
  • 2020-10-10
  • 2019-07-04
相关资源
最近更新 更多