164.扩展User模型-继承AbstractUser

继承自AbstractUser:

如果Abstractuser中定义的字段不能够满足你的项目的要求,并且不想要修改原来User对象上的一些字段,只是想要增加一些字段,那么这时候可以直接继承自django.contrib.auth.models.AbstractUser。其实,这个类也是django.contrib.auth.models.User 的父类。
(1)比如我们想要在原来的User模型的基础上添加一个telephone和school字段,示例代码如下:
from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    telephone = models.CharField(max_length=11, unique=True)
    school = models.CharField(max_length=100)
    
    <!--USERNAME_FIELD代表的是User模型的名字字段的字符串,具有唯一性。如果没有经过修改,默认就是username-->
    <!--现在,我们将它修改为telephone,之后我们对用户进行登录验证的时候,就不用使用username了,而是使用telephone-->
    USERNAME_FIELD = 'telephone'

最重要的是,如果我们使用这种继承的方式修改了Django内置的User模型,那么我们就需要第一次将User模型映射到数据库中的时候就要将User模型定义好。

如果在修改User模型的表的结构之前已经将Django内置的模型映射到数据库中了。那么,我们就需要将数据库中所有的表删除,并且将项目中生成的脚本文件删除。之后重新执行python manage.py makemigrations; python manage.py migrate命令,就可以在数据库中的user表中看到我们新添加的两个字段telephone和school了。
(2)因为我们为User模型添加了两个字段,并且将USERNAME_FIELD='username'改为了USERNAME_FIELD='telephone',如果我们想要调用User.objects.create_user()创建普通用户的话,并且让用户默认必须输入的只读为telephone,username,password,而没有之前的email,那么就可以重写objects上的create_user()方法,示例代码如下:
from django.contrib.auth.models import AbstractUser, BaseUserManager

<!--重写objects上的方法,之所以定义为UserManager类,是因为User.objects.返回的就是UserManager类-->
class UserManager(BaseUserManager):
    <!--创建超级用户和普通用户的差别就是超级用户的is_super=True而普通用户的is_super=False,所以我们可以定义一个普遍的函数用来实现二者的相同的部分,不同的部分就在各个函数中单独定义-->
    <!--定义一个两边有一个下划线的方法,就代表这个方法是受到保护的,只能在这个类中使用-->
    def _create_user_(self,telephone, username, password, **kwargs):
        <!--首先判断telephone是否存在-->
        if not telephone:
            raise ValueError('请输入手机号!')
        if not password:
            raise ValueError('请输入密码!')
        
        <!--self:代表的是当前的这个类,我们要为当前的这个类的模型User创建一个实例化的对象-->
        user = self.model(telephone=telephone, username=username, password=password)
        <!--同样设置密码的话,也可以使用这样的形式-->
        <!--user.set_password(password)-->
        <!--user.save()-->
        return user
    def create_user(self, telephone, username, password, **kwargs):
        kwargs['is_super'] = False
        return self._create_user_(telephone=telephone, username=username, password=password, **kwargs)

    def create_superuser(self, telephone, username, password, **kwargs):
        kwargs['is_super'] = True
        return self._create_user_(telephone=telephone, username=username, password=password, **kwargs)

        
<!--并且需要在重新定义User的模型中,添加objects = UserManager()-->
(3)之后如果想要我们的User模型生效的话,就需要配置settings.py文件中的AUTH_USER_MODEL = 'appname.modelname',在我们的项目中就是:AUTH_USER_MODEL = 'front.User'。
(4)接下来就可以在views.py文件中使用我们重新定义的User模型添加用户了,示例代码如下:
from django.shortcuts import render
from .models import User


def index(request):
    user = User.objects.create_user(telephone="18833332222", username='孤烟逐云', password='111111')
    if user:
        print("创建成功!")
        print('%s' % user.username)
    else:
        print('fail!')
    return render(request,'abstractuser.html')
在我们的数据库表front_user中就可以看到我们创建的用户了。当然了,以上是创建普通用户。
(5)接下来,我们就可以创建超级用户了,只需要将上面代码中的调用create_user()方法换成create_superuser()就可以了,
def index(request):
    user = User.objects.create_superuser(telephone="18833334444", username='小龙虾', password='111111')
    if user:
        print("创建成功!")
        print('%s' % user.username)
    else:
        print('fail!')
    return render(request,'abstractuser.html')
(6)接下来就可以使用Django内置的验证方法进行验证了,示例代码如下:
def index(request):
    # 登录验证
    telephone = request.GET.get('telephone')
    password = request.GET.get('password')
    
    <!--需要注意的是,这里的username对应的值是telephone,因为我们在models.py文件中指定了USERNAME_FIELD='telephone'-->
    user = authenticate(request, username=telephone,password=password)
    if user:
        print('您查找的用户是:%s' % user.username)
    context = {
        'user': user
    }
    return render(request, 'abstractuser.html', context=context)
在浏览器中输入url:http://127.0.0.1:8000/?telephone=********&password=**** ,就会查找出数据库中对应的user。