27_扩展User模型

Posted nichengshishaonian

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了27_扩展User模型相关的知识,希望对你有一定的参考价值。

扩展django的User模型

注意: 继承自AbstractUser和AbstractBaseUser的,要在settings.py 中指定: AUTH_USER_MODEL=‘app名称.模型名称‘

1. 继承自 AbstractUser

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


class UserManager(_UserManager):
    """
    用户管理器
    """
    def create_superuser(self, username, password, email=None, **extra_fields):
        super().create_superuser(username=username, password=password, email=email, **extra_fields)


class User(AbstractUser):
    """
    重写(自定义)用户模型
    """
    mobile = models.CharField(max_length=11, verbose_name='手机号', help_text='手机号', unique=True, error_messages={'unique': '此手机号已经被注册'}, validators=[validators.RegexValidator(r'^1[34579]d{9}$', message='请输入正确的手机号码格式')])
    email_active = models.BooleanField('邮箱状态,是否激活', default=False)

    REQUIRED_FIELDS = ['mobile']
    objects = UserManager()

    class Meta:
        db_table = 'tb_user'
        verbose_name = '用户'     # 在admin 站点中显示名称
        verbose_name_plural = verbose_name    # 复数形式

    def __str__(self):
        return self.username

2. 继承自 AbstractBaseUser和PermissionsMixin

from django.contrib.auth.validators import UnicodeUsernameValidator
from django.db import models
# from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, AbstractUser, BaseUserManager
from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager
from django.contrib.auth.models import PermissionsMixin
from django.core.validators import RegexValidator
from django.core.mail import send_mail

mobile_validator = RegexValidator(r'^1[3-9]d{9}$', '手机号码格式不正确')


class UserManager(BaseUserManager):
    """定义用户管理器"""

    def _create_user(self, username, mobile, password, email, **extra_fields):
        if not username:
            raise ValueError('请输入用户名')
        if not mobile:
            raise ValueError('请输入手机号')

        user = self.model(username=username, mobile=mobile, email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)

        return user

    def create_user(self, username, mobile, password, email=None, **extra_fields):
        """创建普通用户"""
        extra_fields['is_superuser'] = False
        extra_fields.setdefault('is_staff', False)
        return self._create_user(username=username, mobile=mobile, password=password, email=email, **extra_fields)

    def create_superuser(self, username, mobile, password, email=None, **extra_fields):
        """创建超级管理员"""
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        # extra_fields['is_superuser'] = True
        return self._create_user(username=username, mobile=mobile, password=password, email=email, **extra_fields)


class User(AbstractBaseUser, PermissionsMixin):
    """用户模型"""
    username_validator = UnicodeUsernameValidator()
    username = models.CharField(
        '用户名',
        max_length=150,
        unique=True,
        help_text='用户名',
        validators=[username_validator],
        error_messages={
            'unique': '用户已存在,请重新输入',
        }
    )
    mobile = models.CharField(
        '手机号码',
        max_length=11,
        unique=True,
        help_text='手机号码',
        validators=[mobile_validator],
        error_messages={
            'unique': '手机号码已存在, 请重新输入',
            'max_length': '手机号码长度有误',
        })
    email = models.EmailField('邮箱', unique=True, help_text='邮箱', null=True)
    email_active = models.BooleanField('邮箱校验状态', default=False)
    is_staff = models.BooleanField(
        '是否员工,是就能够登录到后台',
        default=False,
        help_text='判断用户是否能够登录到后台admin站点',
    )
    is_active = models.BooleanField(
        '用户是否激活',
        default=True,
        help_text='用户是否激活(活动的),取消此选项,而不是删除用户'
    )
    date_joined = models.DateTimeField(
        '用户加入时间',
        auto_now_add=True
    )

    # 用户管理器
    objects = UserManager()

    EMAIL_FIELD = 'email'
    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['mobile']

    class Meta:
        db_table = 'tb_user'
        verbose_name = '用户'
        verbose_name_plural = verbose_name

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

    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)

    def get_full_name(self):
        return self.username

    def get_short_name(self):
        return self.username

    def __str__(self):
        return self.username

注意:上述两种都要在settings.py文件中指定AUTH_USER_MODEL=‘‘app名.模型名, 不要忘记在settings.py中设置AUTH_USER_MODEL指向它。

2. 一对一外键

如果你对用户验证方法 authenticate 没有其他要求,就是使用 usernamepassword 即可完成。但是想要在原来模型的基础上添加新的字段,那么可以使用 一对一外键 的方式。示例代码如下:

# 一对一外键 扩展用户模型
from django.contrib.auth.models import User
from django.db import models
from django.dispatch import receiver
from django.db.models.signals import post_save

class UserExtension(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='extension')
    telephone = models.CharField(max_length=11, verbose_name='电话号码')
    birthday = models.DateField(null=True, blank=True, verbose_name='出生日期')
    school = models.CharField(max_length=20, verbose_name='学校')

@receiver(post_save, sender=User)
def create_user_extension(sender, instance, created, **kwargs):
    if created:
        UserExtension.objects.create(user=instance)
    else:
        instance.extension.save()

以上是关于27_扩展User模型的主要内容,如果未能解决你的问题,请参考以下文章

扩展 Django 1.11 用户模型

查询扩展用户模型返回错误

在 Django 中使用自定义字段扩展用户模型

在 Django 中扩展用户对象:用户模型继承还是使用 UserProfile?

数据库错误:没有这样的表:auth_user。扩展 AbstractUser 并使用模型在管理员上注册

如何扩展 django oscar 客户模型字段?