【发布时间】: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()。