创建一个自定义的Django用户模型(2)
Settings
把下面这一行添加到settings.py中,以使Django使用新的用户类:
AUTH_USER_MODEL = 'users.CustomUser'
现在,可以创建和应用迁移了,这将创建使用自定义用户模型的新数据库。在开始之前,我们不用创建迁移文件而可以看一下迁移实际上是什么样子,使用--dry-run标志:
(django-custom-user-model)$ python manage.py makemigrations --dry-run --verbosity 3
运行后会看到类似这样的:
# Generated by Django 2.1.5 on 2019-02-06 14:24
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
initial = True
dependencies = [
('auth', '0009_alter_user_last_name_max_length'),
]
operations = [
migrations.CreateModel(
name='CustomUser',
fields=[
('id', models.AutoField(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')),
('first_name', models.CharField(blank=True, max_length=30, verbose_name='first name')),
('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
('email', models.EmailField(max_length=254, unique=True, verbose_name='email address')),
('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={
'verbose_name': 'user',
'verbose_name_plural': 'users',
'abstract': False,
},
),
]
开始创建和应用迁移,要确保迁移不包含username字段:
(django-custom-user-model)$ python manage.py makemigrations
(django-custom-user-model)$ python manage.py migrate
看看数据库的schema:
$ sqlite3 db.sqlite3
SQLite version 3.16.0 2016-11-04 19:09:39
Enter ".help" for usage hints.
sqlite> .tables
auth_group django_migrations
auth_group_permissions django_session
auth_permission users_customuser
django_admin_log users_customuser_groups
django_content_type users_customuser_user_permissions
sqlite> .schema users_customuser
CREATE TABLE "users_customuser" (
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"password" varchar(128) NOT NULL,
"last_login" datetime NULL,
"is_superuser" bool NOT NULL,
"first_name" varchar(30) NOT NULL,
"last_name" varchar(150) NOT NULL,
"is_staff" bool NOT NULL,
"is_active" bool NOT NULL,
"date_joined" datetime NOT NULL,
"email" varchar(254) NOT NULL UNIQUE
);
现在可以使用get_user_model()或settings.AUTH_USER_MODEL引用这个自定义用户模型了。详细信息可参阅官方文档中的引用用户模型,Referencing the User model。
此外,在创建超级用户时,系统会提示您输入电子邮件而不是用户名:
(django-custom-user-model)$ python manage.py createsuperuser
Email address: test@test.com
Password:
Password (again):
Superuser created successfully.
现在要确保tests可以通过了:
----------------------------------------------------------------------
Ran 2 tests in 0.282s
OK
Forms
现在,创建可以使用CustomUser模型的UserCreationForm和UserChangeForm的表单子类。
在users目录下创建一个forms.py文件:
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from .models import CustomUser
class CustomUserCreationForm(UserCreationForm):
class Meta(UserCreationForm):
model = CustomUser
fields = ('email',)
class CustomUserChangeForm(UserChangeForm):
class Meta:
model = CustomUser
fields = ('email',)
Admin
在users/admin.py中创建可以使用上面表单的UserAdmin子类:
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .forms import CustomUserCreationForm, CustomUserChangeForm
from .models import CustomUser
class CustomUserAdmin(UserAdmin):
add_form = CustomUserCreationForm
form = CustomUserChangeForm
model = CustomUser
list_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',)
admin.site.register(CustomUser, CustomUserAdmin)
现在运行server,登录到管理页面可以添加和修改用户了:
Michael Herman是一名软件工程师,也是Real Python的联合创始人和作者。
Michael Herman的个人网站:
https://mherman.org/
Real Python:
https://realpython.com/
Michael Herman的文章:
https://testdriven.io/blog/django-custom-user-model/