Django教程-自定义用户模型
先决条件
安装最新的 Django (2.2 +)
创建 Django 项目
进行基本配置
创建虚拟环境
1.在 Django 中创建自定义用户模型
python manage.py startapp MyUserModel
👉点击领取:最全Python资料合集
INSTALLED_APP = [??????????.MyUserModel]
2. 为自定义用户创建模型
from django.db import modelsfrom django.contrib.auth.models import AbstractBaseUser, PermissionsMixinfrom django.utils import timezonefrom django.utils.translation import gettext_lazy as _from .managers import CustomUserManager# Create your models here.class CustomUser(AbstractBaseUser, PermissionsMixin):username = Noneemail = models.EmailField(_('email_address'), unique=True, max_length = 200)date_joined = models.DateTimeField(default=timezone.now)is_staff = models.BooleanField(default=False)is_active = models.BooleanField(default=True)USERNAME_FIELD = 'email'REQUIRED_FIELDS = []objects = CustomUserManager()def has_perm(self, perm, obj=None):"Does the user have a specific permission?"# Simplest possible answer: Yes, alwaysreturn Truedef is_staff(self):"Is the user a member of staff?"return self.staff@propertydef is_admin(self):"Is the user a admin member?"return self.admindef __str__(self):return self.email
我们来理解一下上面的模型;我们创建了一个名为CustomUser的类,它继承了 AbstractbaseClass。然后,我们添加了电子邮件、is_staff、 is_active和date_joined字段。
用户名设置为 none,因为我们希望通过唯一的电子邮件 ID 而不是用户名来验证用户身份。
如果用户允许登录管理面板,则is_staff返回true。
如果用户当前处于活动状态,则is_active返回true。如果用户不活跃,他/她将不允许登录。
USERNAME_FIELDS定义用户模型的唯一标识 - 电子邮件。
当我们通过createsuperuser命令创建**超级用户时,REQUIRED_FIELDS**会提示字段。它必须包含空白为 False 的任何字段。
管理器类对象指定该类的所有对象都来自 CustomeUserManager 。如果用户拥有每个指定的权限,则has_permission返回true。
3. 创建模型管理器
from django.contrib.auth.base_user import BaseUserManagerfrom django.utils.translation import ugettext_lazy as _"""Custom user model manager where email is the unique identifiersfor authentication instead of usernames."""class CustomUserManager(BaseUserManager):"""Custom user model manager where email is the unique identifiersfor authentication instead of usernames."""def create_user(self, email, password, **extra_fields):"""Create and save a User with the given email and password."""if not email:raise ValueError(_('The Email must be set'))email = self.normalize_email(email)user = self.model(email=email, **extra_fields)user.set_password(password)user.save()return userdef create_superuser(self, email, password, **extra_fields):"""Create and save a SuperUser with the given email and password."""extra_fields.setdefault('is_staff', True)extra_fields.setdefault('is_superuser', True)extra_fields.setdefault('is_active', True)if extra_fields.get('is_staff') is not True:raise ValueError(_('Superuser must have is_staff=True.'))if extra_fields.get('is_superuser') is not True:raise ValueError(_('Superuser must have is_superuser=True.'))return self.create_user(email, password, **extra_fields)def get_full_name(self):'''Returns the first_name plus the last_name, with a space in between.'''full_name = '%s %s' % (self.first_name, self.last_name)return full_name.strip()def get_short_name(self):'''Returns the short name for the user.'''return self.first_name
我们创建了继承 BaseUserManager 的CustomManagerClass 。它提供了以下辅助方法。
create_user ()方法创建、保存并返回用户。它会自动将电子邮件转换为小写,并且返回的 User 对象会将 is_active 设置为 true。
create_superuser ()方法将is_staff和is_active设置为 True。
get_full_name ()返回用户的全名。
get_short_name返回用户的名字。
4. 将自定义用户注册到setting.py
AUTH_USER_MODEL = appName.ClassName
AUTH _USER_MODEL = MyUserModel.CustomUser
python manage.py makemigrationspython manage.py migrate
# Generated by Django 3.2.6 on 2021-08-09 19:55from django.db import migrations, modelsimport django.utils.timezoneclass Migration(migrations.Migration):initial = Truedependencies = [('auth', '0012_alter_user_first_name_max_length'),]operations = [migrations.CreateModel(name='CustomerUser',fields=[('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),('password', models.CharField(max_length=128, verbose_name='password')),('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),('email', models.EmailField(max_length=254, unique=True, verbose_name='email_address')),('is_staff', models.BooleanField(default=False)),('is_active', models.BooleanField(default=True)),('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')),('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')),],options={'abstract': False,},),]
5. 创建超级用户
python manage.py createsuperuser
Email address: [email protected]Password:Password (again):Superuser created successfully.
创建表单来存储用户信息
from django.contrib.auth.forms import UserCreationForm, UserChangeFormfrom django.db.models import fieldsfrom django import formsfrom .models import CustomerUserfrom django.contrib.auth import get_user_modelUser = get_user_model()class CustomUserCreationForm(UserCreationForm):password1 = forms.CharField(widget=forms.PasswordInput)password2 = forms.CharField(label='Confirm Password', widget=forms.PasswordInput)class Meta:model = CustomerUserfields = ('email', )def clean_email(self):email = self.cleaned_data.get('email')qs = User.objects.filter(email=email)if qs.exists():raise forms.ValidationError("Email is taken")return emaildef clean(self):'''Verify both passwords match.'''cleaned_data = super().clean()password1 = cleaned_data.get("password1")password2 = cleaned_data.get("password2")if password1 is not None and password1 != password2:self.add_error("password2", "Your passwords must match")return cleaned_datadef save(self, commit=True):# Save the provided password in hashed formatuser = super().save(commit=False)user.set_password(self.cleaned_data["password1"])if commit:user.save()return userclass CustomUserChangeForm(UserChangeForm):class Meta:model = CustomerUserfields = ('email', )def clean_password(self):# Regardless of what the user provides, return the initial value.# This is done here, rather than on the field, because the# field does not have access to the initial valuereturn self.initial["password1"]
自定义管理面板
from django.contrib import adminfrom django.contrib.auth import authenticatefrom django.contrib.auth.admin import UserAdmin# Register your models here.class CustomUserAdmin(UserAdmin):add_form = CustomUserCreationFormform = CustomUserChangeFormmodel = CustomerUserlist_display = ('email', 'is_staff', 'is_active',)list_filter = ('email', 'is_staff', 'is_active',)fieldsets = ((None, {'fields': ('email', 'password')}),('Permissions', {'fields': ('is_staff', 'is_active')}),)add_fieldsets = ((None, {'classes': ('wide',),'fields': ('email', 'password1', 'password2', 'is_staff', 'is_active')}),)search_fields = ('email',)ordering = ('email',)filter_horizontal = ()admin.site.register(CustomerUser, CustomUserAdmin)
创建一些用户后,管理面板将如下所示。