0

我认为将 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()

由于是从modelCustomUser继承的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 用户密码没有得到散列

django 自定义用户模型密码没有被散列

编辑:我使用以下作为我的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)
4

1 回答 1

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()
于 2021-04-03T12:11:20.477 回答