这是我参与8月更文挑战的第19天,活动详情查看:8月更文挑战
Django 中,自定义用户模型的两种方式是:
- 继承 AbstractUser
- 继承 AbstractBaseUser
注意:如果使用默认的身份验证后端,那么用户模型必须有单一的可以用作身份验证的唯一字段。它可以是用户名、电子邮箱或者其他任何唯一属性。如果想要使用非唯一字段,需要有支持这个功能的自定义身份验证后端。
Django中,对于新项目,最好自定义User模型,即便内置 User 模型的功能满足需求。下面的模型和默认的User模型行为完全一致,但是在未来如果有新的需求,可以对它进行定制化。
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
pass
- 另外在第一次创建或者应用迁移文件之前,还需要把 AUTH_USER_MODEL 指向自定义用户模型。
- 最后,在应用的
admin.py文件中注册自定义用户模型:
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import User
admin.site.register(User, UserAdmin)
继承 AbstractUser 来自定义用户模型示例
- 在
models.py中自定义用户模型以及自定义用户模型管理器
from django.contrib.auth.models import AbstractUser, BaseUserManager
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(AbstractUser):
telephone = models.CharField(max_length=11, unique=True)
school = models.CharField(max_length=100)
USERNAME_FIELD = 'telephone'
REQUIRED_FIELDS = []
objects = UserManager()
AUTH_USER_MODEL = 'front.User'
- 在
views.py中创建用户与验证用户
# 使用 create_user 创建用户
def inherit_AbstractUser1(request):
telephone = '17788889999'
username = 'tuanzi'
password = '123456'
user = User.objects.create_user(telephone=telephone, username=username, password=password)
print(user.username)
return HttpResponse('Django 中自定义用户模型:继承 AbstractUser')
# 使用 create_superuser 创建用户
def inherit_AbstractUser2(request):
telephone = '17799998888'
username = 'super_tuanzi'
password = '123456'
user = User.objects.create_superuser(telephone=telephone, username=username, password=password)
print(user.username)
return HttpResponse('Django 中自定义用户模型:继承 AbstractUser')
# 验证用户
def inherit_AbstractUser3(request):
user = authenticate(request, username='17799998888', password='123456')
if user:
print('验证成功')
print(user.username)
else:
print('验证失败')
return HttpResponse('Django 中自定义用户模型:继承 AbstractUser')
Django 中,构造一个兼容的自定义用户模型的最简方法就是继承 AbstractBaseUser 抽象基类。
我们需要提供一些关键的实现细节:
- USERNAME_FIELD
- EMAIL_FIELD
- REQUIRED_FIELDS
- is_active
- get_full_name()
- get_short_name()
另外,下面的属性和方法在任何 AbstractBaseUser 的子类中都是可用的:
- get_username()
- clean()
- classmethod get_email_field_name()
- classmethod normalize_username(username)
- is_authenticated
- is_anonymous
- set_password(raw_password)
- check_password(raw_password)
- set_unusable_password()
- has_usable_password()
- get_session_auth_hash()
继承 AbstractBaseUser 来自定义用户模型示例
- 在
models.py中自定义模型管理器、自定义用户模型。
from django.contrib.auth.models import (AbstractBaseUser, BaseUserManager,
PermissionsMixin)
from django.db import models
from shortuuidfield import ShortUUIDField
class UserManager(BaseUserManager):
def _create_user(self, telephone, username, password, **kwargs):
if not telephone:
raise ValueError('请传入手机号码!')
if not username:
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, username, password, **kwargs)
def create_superuser(self, telephone, username, password, **kwargs):
kwargs['is_superuser'] = True
kwargs['is_staff'] = True
return self._create_user(telephone, username, password, **kwargs)
class User(AbstractBaseUser, PermissionsMixin):
uid = ShortUUIDField(primary_key=True)
telephone = models.CharField(max_length=11, unique=True)
email = models.EmailField(unique=True, null=True)
username = models.CharField(max_length=100)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
date_joined = models.DateTimeField(auto_now_add=True)
USERNAME_FIELD = 'telephone'
# telephone, username, password
REQUIRED_FIELDS = ['username']
EMAIL_FIELD = 'email'
objects = UserManager()
def get_full_name(self):
return self.username
def get_short_name(self):
return self.username
- 在
settings.py中配置AUTH_USER_MODEL选项。注意只需要应用名加上模型名即可,其他东西不要加。
AUTH_USER_MODEL = 'front.User'
- 第一次生成并运行迁移文件。