django之重构用户表

一、django自定义用户表格式(3.0.0)

数据库:

django之重构用户表

 

 Model类:

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()

    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')
        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)

二、如何重构这个用户表?

  我们在做用户注册和登录时,需要创建一个User表,如果这个用户表包含django自定义的所有字段再加上一个电话号码,那么我们自己再建一个User表包含我们所需的字段是

很麻烦的,有没有什么办法去重构这张表,最后迁移的时候直接生成我们重构够的表?

models.py

from django.db import models
from django.contrib.auth.models import AbstractUser
from django.core import validators

# 在这里重构了django默认的用户表后,还要通知django,使用我重构后的表,需要在设置中声明
# AUTH_USER_MODEL = 'user.User'  应用名.类名

# 继承AbstractUser类
class User(AbstractUser):
    phone = models.CharField(max_length=11, verbose_name="手机号码", unique=True, help_text="手机号码:用于接收验证码",
     validators=[validators.RegexValidator(regex=r"^1[3-8]\d{9}$", message="请输入正确格式的手机号码!")], 
     error_messages={"unique": "您输入的手机号码已经存在!", "required": "手机号码不能为空!"})
    
    REQUIRED_FIELDS = ['phone']

    # 这个类,是对User类的一个说明
    class Meta:
        db_table = "bbs_user"  # 如果不设置,就会是用django默认的数据表命名方式
        verbose_name = "用户表"
        verbose_name_plural = verbose_name

settings.py

AUTH_USER_MODEL = 'user.User'

三、补充

  按照以上步骤,在django3.0.0上是没有问题的,但是如果再django2.1.4就会出现错误

我们来比较一下两个地方

django3.0.0

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=None, password=None, **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)

django2.1.4

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)

区别就在UserManager类下的create_superuser方法,django3.0.0使用了默认参数,而django2.1.4使用了位置参数,在重构时,我们用REQUIRED_FIELDS = ['phone']将

REQUIRED_FIELDS = ['email']覆盖了,因此在使用 >>> python manage.py createsuperuser 创建超级用户时,就不会提示输入邮箱信息,由于再django2.1.4中email为位置蚕食,没有值就会出错,所以为了在django2.1.4中正确重构,必须还要做一些修改
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.core import validators
from django.contrib.auth.models import UserManager as _UserManager


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


# 在这里重构了django默认的用户表后,还要通知django,使用我重构后的表,需要在设置中声明
# AUTH_USER_MODEL = 'user.User'  应用名.类名


# 继承AbstractUser类
class User(AbstractUser):
    phone = models.CharField(max_length=11, verbose_name="手机号码", unique=True, help_text="手机号码:用于接收验证码",
     validators=[validators.RegexValidator(regex=r"^1[3-8]\d{9}$", message="请输入正确格式的手机号码!")], 
     error_messages={"unique": "您输入的手机号码已经存在!", "required": "手机号码不能为空!"})
    
    objects = UserManager()
    
    REQUIRED_FIELDS = ['phone']

    # 这个类,是对User类的一个说明
    class Meta:
        db_table = "bbs_user"  # 如果不设置,就会是用django默认的数据表命名方式
        verbose_name = "用户表"
        verbose_name_plural = verbose_name

 

 

上一篇:python marshmallow库


下一篇:DC 1-3 靶机渗透