注册功能实现 -- 2.用户模型设计

用户模型设计

一、用户表字段分析

  • 添加用户手机号字段
  • 添加邮箱状态字段
  • 迁移操作
    • makemigrations
    • migrate

二、用户模式设计

代码如下所示:

#apps/users/models.py
from django.db import models
from django.contrib.auth.models import AbstractUser, UserManager as _UserManager


# UserManager as _UserManager 这样指定才会正确继承,按照django源码命名
class UserManager(_UserManager):
    """
    重写create_superuser方法,让email默认为空,可以不必传入
    """

    def create_superuser(self, username, password, email=None, **extra_fields):
        super().create_superuser(username=username, password=password, email=email, **extra_fields)


# 定义用户模型完成后,须去settings,指定AUTH_USER_MODEL = 'users.Users' ('app.类名'),否则django不会辨识
class Users(AbstractUser):
    """
    继承AbstractUser类,拥有其所有属性和方法
    add mobile、 email_active fields to Django users modules
    """
    # help_text在api接口文档中会用到
    # verbose_name在admin站点中会用到
    mobile = models.CharField(max_length=11,unique=True,help_text='手机号',verbose_name='手机号',
                              error_messages={
                                  'unique':'此手机号已经注册', # 指定报错的中文信息
                              })
    # bool类型, 默认不激活
    email_active = models.BooleanField(default=False, verbose_name='邮箱验证状态')

    REQUIRED_FIELDS = ['mobile'] # 重写, 必须输入mobile

    # 自定义管理器 此项必须加入,方可让重写的create_superuser方法执行,
    # 由于程序自上而下执行,所以调用关系 UserManager再本类之上
    objects = UserManager()

    # 元数据 User下面的子类Meta,
    class Meta:
        # 若不指定会以app_类名小写作为数据库名称,开发会对数据库命名有要求
        db_table = 'tb_users'  #数据库名以tb_开头
        verbose_name = '用户'  #指在admin战点显示的中文信息
        verbose_name_plural = verbose_name #复数形式,英文会用到,中文默认verbose_name

    # 打印实例化对象时 会调用该方法
    def __str__(self):
        return self.username

在settings.py文件中添加如下配置:

# 指定自定义用户模型

# 有了上述简化代码的三部操作 sys.path.insert(0, BASE_DIR) sys.path.insert(1, os.path.join(BASE_DIR, 'apps'))
# 不用apps.users.Users

AUTH_USER_MODEL = 'users.Users'

源码详情

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)

    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)
    
    
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.
    """
    username_validator = UnicodeUsernameValidator()
    # CharField()必须带有max_length属性
    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."),
        },
    )
    # None=True属性 针对数据库允许为空
    # blank=True属性 针对校验,前端可以不传这个参数,可以理解form表单为空
    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字段,是否有权限进入后台
    is_staff = models.BooleanField(
        _('staff status'),
        default=False,
        help_text=_('Designates whether the user can log into this admin site.'),
    )
     # is_active'字段,用户是否活跃
    is_active = models.BooleanField(
        _('active'),
        default=True,
        help_text=_(
            'Designates whether this user should be treated as active. '
            'Unselect this instead of deleting accounts.'
        ),
    )
    # DateTimeField字段必须设置default=timezone.now
    date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
    # 用户管理器 objects.get等一些操作查询用户
    objects = UserManager()

    EMAIL_FIELD = 'email' # google查询 字段重命名 指email名称
    USERNAME_FIELD = 'username' # 指用户名称
    REQUIRED_FIELDS = ['email'] # 必须添加email参数

    class Meta:
        verbose_name = _('user')
        verbose_name_plural = _('users')
        abstract = 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)

你可能感兴趣的:(注册功能实现 -- 2.用户模型设计)