当我们要自定义的 User model 的时候,应该考虑以下几点:
1. 模型必须有一个唯一的字段可被用于识别目的。可以是一个用户名,电子邮件地址,或任何其它独特属性。
2. 你的模型必须提供一种方法可以在 "short" and "long" form 可以定位到用户。最普遍的方法是用用户的名来作为简称,用用户的全名来作为全称。然而,对这两种方式没有特定的要求,如果你想,他们可以返回完全相同的值。
创建一个规范的自定义模型最简单的方法是继承 AbstractBaseUser,并且创建一个继承自 BaseUserManager 的新的 UserManager 来管理我们自定义的 User 模型。
以下是一个完整例子。
新建一个 myUserApp 来作为自定义 User 的 App。
编写 models.py,MyUser 就是我们自定义的 User 模型,MyUserManager 是它的管理器:
from django.db import models
from django.contrib.auth.models import (
BaseUserManager, AbstractBaseUser
)
class MyUserManager(BaseUserManager):
# 用 email,date_of_birth 和密码创建一个新用户
def create_user(self, email, date_of_birth, password=None):
if not email:
raise ValueError('Users must have an email address')
user = self.model(
email=self.normalize_email(email),
date_of_birth=date_of_birth,
)
user.set_password(password)
user.save(using=self._db)
return user
# 用 email,date_of_birth 和密码创建一个新的超级用户
def create_superuser(self, email, date_of_birth, password):
user = self.create_user(email,
password=password,
date_of_birth=date_of_birth
)
user.is_admin = True
user.save(using=self._db)
return user
class MyUser(AbstractBaseUser):
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True,
)
date_of_birth = models.DateField()
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
# 指定 MyUser 模型的管理器
objects = MyUserManager()
# 描述User模型上用作唯一标识符的字段名称
# 字段必须必须是唯一的(即在其定义中设置unique=True)
USERNAME_FIELD = 'email'
# 当通过createsuperuser管理命令创建一个用户时
# 系统会提示用户输入以下字段
REQUIRED_FIELDS = ['date_of_birth']
# 返回 email 地址
def get_full_name(self):
return self.email
# 返回 email 地址
def get_short_name(self):
return self.email
def __str__(self): # __unicode__ on Python 2
return self.email
def has_perm(self, perm, obj=None):
"Does the user have a specific permission?"
# Simplest possible answer: Yes, always
return True
def has_module_perms(self, app_label):
"Does the user have permissions to view the app `app_label`?"
# Simplest possible answer: Yes, always
return True
@property
def is_staff(self):
"Is the user a member of staff?"
# Simplest possible answer: All admins are staff
return self.is_admin
在 setting.py 中加上以下内容:
AUTH_USER_MODEL = 'myUserApp.MyUser'
现在我们自定义的 User 模型创建好了。它要求使用 email 而非用户名来作为登陆的依据。
在 shell 中检验我们自定义的 User 模型。
创建用户:
from myUserApp.models import MyUser
u = MyUser.objects.create_user(email='diego@django.com', date_of_birth='1999-1-1', password='diego12345')
u
>>> <MyUser: diego@django.com>
验证用户:
from django.contrib.auth import authenticate
u = authenticate(email='diego@django.com', password='diego12345')
u
>>> <MyUser: diego@django.com>
** 获取用户:**
BaseUserManager 提供一个 get_by_natural_key(username) 方法,通过 USERNAME_FIELD (本例中是:"email") 指定的字段来获取用户实例。
u = MyUser.objects.get_by_natural_key('diego@django.com')
u
>>> <MyUser: diego@django.com>
也可以用 get 方法:
u = MyUser.objects.get(email='diego@django.com')
u
>>> <MyUser: diego@django.com>