码迷,mamicode.com
首页 > 其他好文 > 详细

django之重构用户表

时间:2020-03-02 20:52:38      阅读:73      评论:0      收藏:0      [点我收藏+]

标签:port   验证   table   cti   ast   src   mod   数据库   into   

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

数据库:

技术图片

 

 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

 

 

django之重构用户表

标签:port   验证   table   cti   ast   src   mod   数据库   into   

原文地址:https://www.cnblogs.com/loveprogramme/p/12397685.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!