第一种方法proxy
如果你对Django
提供的字段,以及验证的方法都比较满意,没有什么需要改的。但是只是需要在他原有的基础之上增加一些操作的方法。那么建议使用这种方式。示例代码如下:
#在model.py下 class Person(User): class Meta: proxy = True def get_blacklist(self): return self.objects.filter(is_active=False)
在以上,我们定义了一个Person
类,让他继承自User
,并且在Meta
中设置proxy=True
,说明这个只是User
的一个代理模型。他并不会影响原来User
模型在数据库中表的结构。以后如果你想方便的获取所有黑名单的人,那么你就可以通过Person.get_blacklist()
就可以获取到。并且User.objects.all()
和Person.objects.all()
其实是等价的。因为他们都是从User
这个模型中获取所有的数据。
第二种一对一外键
如果你对用户验证方法authenticate
没有其他要求,就是使用username
和password
即可完成。但是想要在原来模型的基础之上添加新的字段,那么可以使用一对一外键的方式。示例代码如下:
from django.contrib.auth.models import User from django.db import models from django.dispatch import receiver from django.db.models.signals import post_save class UserExtension(models.Model): user = models.OneToOneField(User,on_delete=models.CASCADE,related_name='extension') birthday = models.DateField(null=True,blank=True) school = models.CharField(max_length=100) @receiver(post_save,sender=User) def create_user_extension(sender,instance,created,**kwargs): if created: UserExtension.objects.create(user=instance) else: instance.extension.save()
以上定义一个UserExtension
的模型,并且让她和User
模型进行一对一的绑定,以后我们新增的字段,就添加到UserExtension
上。并且还写了一个接受保存模型的信号处理方法,只要是User
调用了save
方法,那么就会创建一个UserExtension
和User
进行绑定。
第三种继承自AbstractUser
:
对于authenticate
不满意,并且不想要修改原来User
对象上的一些字段,但是想要增加一些字段,那么这时候可以直接继承自django.contrib.auth.models.AbstractUser
,其实这个类也是django.contrib.auth.models.User
的父类。比如我们想要在原来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) # 指定telephone作为USERNAME_FIELD,以后使用authenticate # 函数验证的时候,就可以根据telephone来验证 # 而不是原来的username USERNAME_FIELD = 'telephone' REQUIRED_FIELDS = [] # 重新定义Manager对象,在创建user的时候使用telephone和 # password,而不是使用username和password objects = UserManager() class UserManager(BaseUserManager): use_in_migrations = True def _create_user(self,telephone,password,**extra_fields): if not telephone: raise ValueError("请填入手机号码!") user = self.model(telephone=telephone,*extra_fields) user.set_password(password) user.save() return user def create_user(self,telephone,password,**extra_fields): extra_fields.setdefault('is_superuser',False) return self._create_user(telephone,password) def create_superuser(self,telephone,password,**extra_fields): extra_fields['is_superuser'] = True return self._create_user(telephone,password)
然后再在settings
中配置好AUTH_USER_MODEL=youapp.User
。
这种方式因为破坏了原来User模型的表结构,所以必须要在第一次migrate
前就先定义好。
第四种继承自AbstractBaseUser
模型:
如果你想修改默认的验证方式,并且对于原来User
模型上的一些字段不想要,那么可以自定义一个模型,然后继承自AbstractBaseUser
,再添加你想要的字段。这种方式会比较麻烦,最好是确定自己对Django
比较了解才推荐使用。步骤如下:
-
创建模型。示例代码如下:
class User(AbstractBaseUser,PermissionsMixin): email = models.EmailField(unique=True) username = models.CharField(max_length=150) telephone = models.CharField(max_length=11,unique=True) is_active = models.BooleanField(default=True) USERNAME_FIELD = 'telephone' REQUIRED_FIELDS = [] objects = UserManager() def get_full_name(self): return self.username def get_short_name(self): return self.username
其中password
和last_login
是在AbstractBaseUser
中已经添加好了的,我们直接继承就可以了。然后我们再添加我们想要的字段。比如email
、username
、telephone
等。这样就可以实现自己想要的字段了。但是因为我们重写了User
,所以应该尽可能的模拟User
模型:
-
USERNAME_FIELD
:用来描述User
模型名字字段的字符串,作为唯一的标识。如果没有修改,那么会使用USERNAME
来作为唯一字段。REQUIRED_FIELDS
:一个字段名列表,用于当通过createsuperuser
管理命令创建一个用户时的提示。is_active
:一个布尔值,用于标识用户当前是否可用。get_full_name()
:获取完整的名字。get_short_name()
:一个比较简短的用户名。
-
重新定义
UserManager
:我们还需要定义自己的UserManager
,因为默认的UserManager
在创建用户的时候使用的是username
和password
,那么我们要替换成telephone
。示例代码如下:
class UserManager(BaseUserManager): use_in_migrations = True def _create_user(self,telephone,password,**extra_fields): if not telephone: raise ValueError("请填入手机号码!") user = self.model(telephone=telephone,*extra_fields) user.set_password(password) user.save() return user def create_user(self,telephone,password,**extra_fields): extra_fields.setdefault('is_superuser',False) return self._create_user(telephone,password) def create_superuser(self,telephone,password,**extra_fields): extra_fields['is_superuser'] = True return self._create_user(telephone,password)
-
-
在创建了新的
User
模型后,还需要在settings
中配置好。配置AUTH_USER_MODEL='appname.User'
。 -
如何使用这个自定义的模型:比如以后我们有一个
Article
模型,需要通过外键引用这个User
模型,那么可以通过以下两种方式引用。
第一种就是直接将User
导入到当前文件中。示例代码如下:
-
from django.db import models from myauth.models import User class Article(models.Model): title = models.CharField(max_length=100) content = models.TextField() author = models.ForeignKey(User, on_delete=models.CASCADE)
这种方式是可以行得通的。但是为了更好的使用性,建议还是将User
抽象出来,使用settings.AUTH_USER_MODEL
来表示。示例代码如下:
from django.db import models from django.conf import settings class Article(models.Model): title = models.CharField(max_length=100) content = models.TextField() author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
这种方式因为破坏了原来User模型的表结构,所以必须要在第一次migrate
前就先定义好。