扩展/定制用户认证系统
本小节参照官方帮助文档,扩展Django的User类,实现用户信息的录入和管理。
Customizing authentication in Django(https://docs.djangoproject.com/en/4.1/topics/auth/customizing/)。按照官方文档,有多种方式可以进行User模型重构或者扩展,本小节采用其中有扩展用户模型部分Extending the existing User model,参照其中的扩展User模型方法,构建教师简介信息管理模块。
构建teacher app
python manage.py startapp teacher
修改settings
INSTALLED_APPS = [
...
'teacher',
]
修改项目的urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('teacher/', include('teacher.urls')),
]
teacher app下创建文件urls.py
拓展User 模型
from django.urls import path
from . import views
urlpatterns = [
# path('', views.index, name='index'), 具体路径后面再加入
]
创建Teacher模型
修改app哦models.py,模型中引入django系统的User模型,按照OneToOneField进行字段表关联,扩展用户信息。
每个字段中verbose_name='用户名称' 设置中文字段名称。
unique_together = ("full_name", "work_num") 设置表主键,
verbose_name = "教师信息" 设置表的中文名称
verbose_name_plural = verbose_name 设置表的复数中文名称
为了后续引入import-export插件导入数据,所有字段设置了blank=True和null=True
from django.db import models
from django.contrib.auth.models import User
class Teacher(models.Model):
username = models.OneToOneField(User, blank=True, null=True, on_delete=models.CASCADE, verbose_name='用户名称')
full_name = models.CharField(blank=True, null=True, max_length=20, verbose_name="姓名")
work_num = models.CharField(blank=True, null=True, max_length=20, verbose_name="工号")
head_title = models.CharField(blank=True, null=True, max_length=20, verbose_name="职称")
employ_type = models.CharField(blank=True, null=True, max_length=20, verbose_name="聘用类型")
employ_date = models.DateField(blank=True, null=True, verbose_name="聘用日期")
use_type = models.CharField(blank=True, null=True, max_length=20, verbose_name="编制类型")
IDNumber = models.CharField(blank=True, null=True, max_length=20, verbose_name="身份证号")
department = models.CharField(blank=True, null=True, max_length=100, verbose_name="部门")
def __str__(self):
return self.full_name
class Meta:
unique_together = ("full_name", "work_num")
verbose_name = "教师信息"
verbose_name_plural = verbose_name
加入django-import-export插件
在项目中引入表格批量导入导出功能。
安装import-export
pip install django-import-export
设置settings.py
INSTALLED_APPS = (
...
'import_export',
)
收集静态文件
部署之前需要收集静态文件
python manage.py collectstatic
import-export 设置
设置主文件夹下的settings.py文件
IMPORT_EXPORT_USE_TRANSACTIONS = True
新建resources.py文件
新建import-export需要的资源文件,在其中新建导入的表的资源。
from import_export import resources
from import_export.fields import Field
from import_export.widgets import ForeignKeyWidget
from .models import Teacher
from django.contrib.auth.models import User
class TeacherResource(resources.ModelResource):
# 关联系统User 模型
username = Field(attribute="username", column_name="用户名称", widget=ForeignKeyWidget(User, 'username'))
full_name = Field(attribute='full_name', column_name='姓名')
work_num = Field(attribute='work_num', column_name='工号')
head_title = Field(attribute='head_title', column_name='职称')
employ_type = Field(attribute='employ_type', column_name='聘用类型')
employ_date = Field(attribute='employ_date', column_name='聘用日期')
use_type = Field(attribute='use_type', column_name='编制类型')
IDNumber = Field(attribute='IDNumber', column_name='身份证号')
department = Field(attribute='department', column_name='部门')
class Meta:
model = Teacher
import_id_fields = ['full_name', 'work_num']
# 导入前检查是否存在用户,不存在这创建用户,如果存在则将用户关联到模型
def before_import(self, dataset, using_transactions, dry_run, **kwargs):
for work_num in dataset['工号']:
username = str(work_num)
password = "dxd@" + str(123456)
if not User.objects.filter(username=username).exists():
User.objects.create_user(username=work_num, password=password, is_staff=True, is_superuser=False)
修改app的admin.py
在django自带的后台中添加导入表的类和导入导出资源类。
from django.contrib import admin
from import_export.admin import ImportExportModelAdmin
from .models import Teacher
from .resources import TeacherResource
class TeacherAdmin(ImportExportModelAdmin):
resource_class = TeacherResource
list_display = ("username", "full_name", "work_num", "head_title", "employ_type",
"employ_date", "use_type", "IDNumber", "department")
ordering = ["work_num", ]
# 注册app的admin
admin.site.register(Teacher, TeacherAdmin)
中文化模型app
修改app的apps.py文件,设置后可以在django自带后台中显示表的中文名称。
from django.apps import AppConfig
class TeacherConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'teacher'
verbose_name = "教师信息管理"
verbose_name_plural = verbose_name
迁移数据
python manage.py makemigrations
python manage.py migrate
由于扩展了User模型,需要进行数据库清空,创建新的超级用户
python manage.py flush # 清空数据库
python manage.py createsuperuser
批量读入excel教师信息,创建用户
登录管理员用户
导入教师信息
导入/导出功能都已实现。还可以进一步优化导出的配置,比如字段顺序等。因为前期已经为字段都设置了别名verbose_name和列名column_name,因此导出已经是中文字段名称。