django自定义User

django自定义用户

INSTALLED_APPS = [
    'django.contrib.admin',
    #包含一个核心授权框架,以及大部分的模型定义。
    'django.contrib.auth',
    #content type 系统,可以用来关联model和权限
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',  #用来管理session
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',   #用来处理和当前session相关联的用户。
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

1、django用户

在这里插入图片描述
django.contrib.auth.models.User

class User(AbstractUser):
    """
    Users within the Django authentication system are represented by this
    model.

    Username and password are required. Other fields are optional.
    """
    class Meta(AbstractUser.Meta):
        swappable = 'AUTH_USER_MODEL'

继承了AbstractUser这个抽象类,AbstractUser 源码(是一个抽象类)
它基本完成了注册的基础功能,如果想要在定义user,可以继承进行添加方法。

class AbstractUser(AbstractBaseUser, PermissionsMixin):
    """
    An abstract base class implementing a fully featured User model with
    admin-compliant permissions.

    Username and password are required. Other fields are optional.
    一个抽象基类,它使用
	admin-compliant权限。
	需要用户名和密码。其他字段是可选的。
    """
    username_validator = UnicodeUsernameValidator()

    username = models.CharField(
        _('username'),
        max_length=150,
        unique=True,
        help_text=_('Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.'),
        validators=[username_validator],
        error_messages={
            'unique': _("A user with that username already exists."),
        },
    )
    first_name = models.CharField(_('first name'), max_length=30, blank=True)
    last_name = models.CharField(_('last name'), max_length=150, blank=True)
    email = models.EmailField(_('email address'), blank=True)
    is_staff = models.BooleanField(
        _('staff status'),
        default=False,
        help_text=_('Designates whether the user can log into this admin site.'),
    )
    is_active = models.BooleanField(
        _('active'),
        default=True,
        help_text=_(
            'Designates whether this user should be treated as active. '
            'Unselect this instead of deleting accounts.'
        ),
    )
    date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
	
	用户管理器(创建用户时会使用到)
    objects = UserManager()

    EMAIL_FIELD = 'email'
    USERNAME_FIELD = 'username'  
    REQUIRED_FIELDS = ['email']    #必填字段(邮箱)

    class Meta:
        verbose_name = _('user')     # 在admin站点中显示名称
        verbose_name_plural = _('users')     #复数
        abstract = True (当为True是就是一个抽象类)

    def clean(self):
        super().clean()
        self.email = self.__class__.objects.normalize_email(self.email)

    def get_full_name(self):
        """
        Return the first_name plus the last_name, with a space in between.
        """
        full_name = '%s %s' % (self.first_name, self.last_name)
        return full_name.strip()

    def get_short_name(self):
        """Return the short name for the user."""
        return self.first_name

    def email_user(self, subject, message, from_email=None, **kwargs):
        """Send an email to this user."""
        send_mail(subject, message, from_email, [self.email], **kwargs)
内置的User模型拥有以下的字段:

username:用户名。150个字符以内。可以包含数字和英文字符,以及_、@、+、.和-字符。不能为空,且必须唯一!

first_name:first_name,在30个字符以内。可以为空。

last_name:last_name,在150个字符以内。可以为空。

email:邮箱。可以为空。

password:密码。经过哈希过后的密码。

is_staff:是否可以进入到admin的站点。代表是否是员工。

is_active:是否是可用的。对于一些想要删除账号的数据,我们设置这个值为False就可以了,而不是真正的从数据库中删除。

is_superuser:是否是超级管理员。如果是超级管理员,那么拥有整个网站的所有权限。

last_login:上次登录的时间。

date_joined:账号创建的时间。

可以看到,Django内建的User模型可能不适合某些类型的项目。因此我们需要
自定义的 User model 满足我们的要求。
django的强大之处在于开发效率高,内置了权限模块之类的很多常用功能。在开始一个新的django项目时,如果权限模块中的User模型不满足项目要求,我们需要扩展或者自定义User模型。

扩展User模型有两种方法:

1、如果你不需要改变数据库存储内容,只是改变行为,那么可以建立有一个基于User模型的代理模型。
2、如果想存储与User模型关联的信息,可以使用OneToOneField到包含其他信息字段的模型。这种one-to-one模型经常被称作Profile模型,因为它可能存储站点用户的非身份验证的相关信息。例如:

   from django.contrib.auth.models import User
   
   class Employee(models.Model):
       user = models.OneToOneField(User, on_delete=models.CASCADE)
       department = models.CharField(max_length=100)
自定义User模型:

开启一个新项目,官方强烈推荐用户自定义用户模型,即是默认的用户模型目前已经足够,但是未来可能会要扩展。

from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    pass

注意:不要忘记在settings.py中设置AUTH_USER_MODEL指向它。

一旦已经创立数据库表之后再去修改AUTH_USER_MODEL,会困难很多,因为它会影响外键和多对多关系。这个改动并不能自动完成,需要手动修复(巨坑)。
例如:我们要添加一个手机验证功能

from django.db import models
from django.contrib.auth.models import AbstractUser, UserManager as _UserManager


class UserManager(_UserManager):
    """
    自定义 user manager 修改在使用`python manage.py createsuperuser`命令时
    可以提供email,修改用户管理器中的创建超级用户
    """
    def create_superuser(self, username, password, email=None, **extra_fields):
        return super().create_superuser(username=username, password=password, email=email, **extra_fields)


class User(AbstractUser):
    """
    add mobile, email_active fields to Django user model.
    """
    mobile = models.CharField('手机号', max_length=11, unique=True, help_text='手机号', error_messages={'unique': '此手机号码已注册'})

    email_active = models.BooleanField('邮箱状态', default=False)
  
 	#元信息
    class Meta:
        db_table = 'tb_user'    # 指定数据库表名
        verbose_name = '用户'     # 在admin站点中显示名称
        verbose_name_plural = verbose_name  # 显示复数
        
    #打印
    def __str__(self):
        return self.username

    # A list of the field names that will be prompted for
    # when create a user via createsuperuser management command.
    #通过creatsuperuser 这个命令创建用户时,需要的字段,必填字段,改为手机
    REQUIRED_FIELDS = ['mobile']
    
    # specify manager
    #如果你想修改必须输入email的这个行为
    # 复写用户管理器
    objects = UserManager()

UserManager源代码

class UserManager(BaseUserManager):
    use_in_migrations = True

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

    def create_user(self, username, email=None, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', False)
        extra_fields.setdefault('is_superuser', False)
        return self._create_user(username, email, password, **extra_fields)

 #可以看到默认创建超级用户(必须使用email),因此我们要重写方法。
 
    def create_superuser(self, username, email, password, **extra_fields):
        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(username, email, password, **extra_fields)

在一个新项目开始第一次模型迁移之前,一定要先写好自定义用户模型写好models代码后,一定要在settings配置文件修改使用的user:
在这里插入图片描述
数据库迁移完成后:
在这里插入图片描述

发布了12 篇原创文章 · 获赞 1 · 访问量 995

猜你喜欢

转载自blog.csdn.net/fksfdh/article/details/100858537