一、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