自带的用户模型,AbstractUser还是有些缺陷,比如,first_name、last_name这些字段不想要。所以,要自定义字段,需要重写AbstractUser.
因为class AbstractUser(AbstractBaseUser, PermissionsMixin), 所以重写的时候也需要同时继承AbstractBaseUser, PermissionsMixin
1、app01/models.py里面自定义User模型
from django.db import models from django.contrib.auth.models import BaseUserManager, AbstractBaseUser, PermissionsMixin class UserManager(BaseUserManager): def _create_user(self , telephone, username, password, **kwargs): if not telephone: raise ValueError("必须要传递手机号码!") if not password: raise ValueError("必须要传递密码") user = self.model( telephone = telephone, username= username , **kwargs) user.set_password( password ) user.save() return user def create_user(self, telephone, username, password, **kwargs): # kwargs[‘is_superuser‘] = False return self._create_user( telephone = telephone, username=username, password = password, **kwargs ) def create_superuser(self, telephone, username, password, **kwargs): # kwargs[‘is_superuser‘] = True return self._create_user( telephone = telephone, username=username, password = password, **kwargs ) class User(AbstractBaseUser, PermissionsMixin): telephone = models.CharField(max_length=11, unique=True) email = models.CharField(max_length=100, unique=True) username = models.CharField(max_length=100) is_active = models.BooleanField(default=True) USERNAME_FIELD = "telephone" #USERNAME_FIELD作用,是执行authenticate验证, username参数传入后,实际校验的是telephone字段 REQUIRED_FIELDS = [] objects = UserManager() def get_full_name(self): return self.username def get_short_name(self): return self.username
2、在settings.py里面设置AUTH_USER_MODEL,这样django就不使用系统默认的User模型,而使用app01/models.py里面的User模型
3、创建模型后,需要执行makemigrations和migrate同步数据库,同步后数据库表列就是自定义的
4、app01/views.py视图里调用模型,创建和认证用户
from django.shortcuts import render, HttpResponse from django.db import connection from app01.models import User from django.contrib.auth import authenticate def test(request): #创建用户 # User.objects.create_user( telephone="15555655555", password="555555", username="zhiliao5" ) #用认证 user = authenticate(request, username="15555655555", password="555555") if user: print(user.username) print("验证成功!") else: print("验证失败!") return HttpResponse("继承AbstractUser扩展用户")
5、创建用户和认证用户的结果如下:
创建用户:
认证用户:
System check identified no issues (0 silenced). November 06, 2019 - 17:58:38 Django version 2.2.2, using settings ‘untitled1019.settings‘ Starting development server at http://127.0.0.1:8080/ Quit the server with CTRL-BREAK. zhiliao5 验证成功!
6、如果现在有一个模型Article和User模型关联,有一个get_user_model的方法,会自动获取settings.py里面设置的用户模型,这样更安全
from django.db import models from django.contrib.auth.models import BaseUserManager, AbstractBaseUser, PermissionsMixin from django.contrib.auth import get_user_model class UserManager(BaseUserManager): def _create_user(self , telephone, username, password, **kwargs): if not telephone: raise ValueError("必须要传递手机号码!") if not password: raise ValueError("必须要传递密码") user = self.model( telephone = telephone, username= username , **kwargs) user.set_password( password ) user.save() return user def create_user(self, telephone, username, password, **kwargs): # kwargs[‘is_superuser‘] = False return self._create_user( telephone = telephone, username=username, password = password, **kwargs ) def create_superuser(self, telephone, username, password, **kwargs): # kwargs[‘is_superuser‘] = True return self._create_user( telephone = telephone, username=username, password = password, **kwargs ) class User(AbstractBaseUser, PermissionsMixin): telephone = models.CharField(max_length=11, unique=True) email = models.CharField(max_length=100, unique=True) username = models.CharField(max_length=100) is_active = models.BooleanField(default=True) USERNAME_FIELD = "telephone" #USERNAME_FIELD作用,是执行authenticate验证, username参数传入后,实际校验的是telephone字段 REQUIRED_FIELDS = [] objects = UserManager() def get_full_name(self): return self.username def get_short_name(self): return self.username class Article(models.Model): title = models.CharField(max_length=100) content = models.TextField() # author = models.ForeignKey( User, on_delete= models.CASCADE ) #get_user_model()会自动获取settings.py里面 AUTH_USER_MODEL,这样不管你定义的那个User,都可以自动获取,更安全 author = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
7、执行makemigrations和migrate同步数据库以后,就会产生一张app01_articel表, 并且与User建立了外键关系
django扩展用户模型继承AbstractBaseUser
原文:https://www.cnblogs.com/harryTree/p/11807019.html