当前位置: 首页 > news >正文

创建专属的实验室应用

创建一个专门的 lab应用

#进入你的 Django 项目根目录

python manage.py startapp lab

配置 settings.py

打开项目根目录下的 settings.py,在INSTALLED_APPS里添加lab应用

INSTALLED_APPS = [ "polls.apps.PollsConfig", 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'lab', # 新增这一行 ]

替换 lab/models.py 代码

from django.db import models from django.utils import timezone from datetime import datetime # 实验室模型 class Laboratory(models.Model): # 安全等级选项 SAFETY_LEVELS = [ ('1', '一级'), ('2', '二级'), ('3', '三级'), ] name = models.CharField(max_length=100, verbose_name="实验室名称") lab_id = models.CharField(max_length=20, unique=True, verbose_name="实验室编号") room_number = models.CharField(max_length=20, verbose_name="房间号") created_date = models.DateField(auto_now_add=True, verbose_name="创建年月") updated_date = models.DateField(auto_now=True, verbose_name="最近更新年月") manager = models.ForeignKey('LabTechnician', on_delete=models.SET_NULL, null=True, related_name='managed_labs', verbose_name="管理员") area = models.FloatField(verbose_name="面积") seats = models.IntegerField(verbose_name="座位数") safety_level = models.CharField(max_length=1, choices=SAFETY_LEVELS, verbose_name="安全等级") computers = models.IntegerField(verbose_name="电脑数") other_equipment = models.TextField(blank=True, verbose_name="其他主要设备") notes = models.TextField(blank=True, verbose_name="备注") def __str__(self): return f"{self.name} ({self.room_number})" # 学期模型 class Semester(models.Model): name = models.CharField(max_length=20, verbose_name="学期名称") start_date = models.DateField(verbose_name="起始日期") is_active = models.BooleanField(default=True, verbose_name="是否激活") def __str__(self): return self.name # 教师模型 class Teacher(models.Model): # 专业选项 MAJORS = [ ('CS', '计算机'), ('SE', '软件工程'), ('BD', '大数据'), ('EC', '电商'), ] name = models.CharField(max_length=100, verbose_name="姓名") phone = models.CharField(max_length=20, verbose_name="联系电话") major = models.CharField(max_length=2, choices=MAJORS, verbose_name="所属专业") is_external = models.BooleanField(default=False, verbose_name="是否校外") def __str__(self): return self.name # 实验员模型 class LabTechnician(models.Model): name = models.CharField(max_length=100, verbose_name="姓名") phone = models.CharField(max_length=20, verbose_name="联系电话") def __str__(self): return self.name # 实验员值班安排模型 class LabDuty(models.Model): # 星期选项 DAYS = [(i, day) for i, day in enumerate(['周一', '周二', '周三', '周四', '周五'], 1)] # 班次选项 SHIFTS = [('morning', '早8点前'), ('evening', '晚5点后')] technician = models.ForeignKey(LabTechnician, on_delete=models.CASCADE, related_name='duties', verbose_name="实验员") day = models.IntegerField(choices=DAYS, verbose_name="星期") shift = models.CharField(max_length=10, choices=SHIFTS, verbose_name="班次") class Meta: unique_together = ('technician', 'day', 'shift') # 避免同一实验员同一天同一班次重复安排 def __str__(self): return f"{self.technician.name} - {self.get_day_display()} {self.get_shift_display()}" # 课程模型 class Course(models.Model): MAJORS = [ ('CS', '计算机'), ('SE', '软件工程'), ('BD', '大数据'), ('EC', '电商'), ('IC', '集成电路微专业'), ('OS', '开源微专业'), ] name = models.CharField(max_length=100, verbose_name="课程名称") majors = models.JSONField(default=list, verbose_name="所属专业") # 支持多个专业 def __str__(self): return self.name # 软件模型 class Software(models.Model): LICENSE_TYPES = [ ('free', '免费'), ('paid', '收费'), ('cracked', '收费破解'), ] name = models.CharField(max_length=100, verbose_name="软件名称") version = models.CharField(max_length=20, verbose_name="软件版本") license = models.CharField(max_length=10, choices=LICENSE_TYPES, verbose_name="收费状态") def __str__(self): return f"{self.name} {self.version}" # 实验室使用登记模型 class LabUsageRecord(models.Model): date = models.DateField(default=timezone.now, verbose_name="使用日期") semester = models.ForeignKey(Semester, on_delete=models.CASCADE, verbose_name="学期") course = models.ForeignKey(Course, on_delete=models.CASCADE, verbose_name="课程") labs = models.ManyToManyField(Laboratory, verbose_name="使用实验室") software = models.ManyToManyField(Software, verbose_name="使用软件") user_type = models.CharField(max_length=10, choices=[('teacher', '教师'), ('technician', '实验员')], verbose_name="使用者类型") teacher = models.ForeignKey(Teacher, on_delete=models.SET_NULL, null=True, blank=True, verbose_name="教师") technician = models.ForeignKey(LabTechnician, on_delete=models.SET_NULL, null=True, blank=True, verbose_name="实验员") major = models.CharField(max_length=2, choices=Teacher.MAJORS, verbose_name="所属专业") # 自动填充学期和专业的逻辑 def save(self, *args, **kwargs): # 自动关联当前日期对应的学期 if not self.semester_id: today = self.date or timezone.now().date() semester = Semester.objects.filter(start_date__lte=today).order_by('-start_date').first() if semester: self.semester = semester # 自动填充专业 if self.teacher and not self.major: self.major = self.teacher.major super().save(*args, **kwargs) def __str__(self): return f"{self.course.name} - {self.date}" # 实验室运维日志模型 class LabMaintenance(models.Model): lab = models.ForeignKey(Laboratory, on_delete=models.CASCADE, verbose_name="实验室") issue = models.TextField(verbose_name="故障/维护情况") discovered_date = models.DateField(default=timezone.now, verbose_name="发现/处理日期") solved = models.BooleanField(default=False, verbose_name="是否解决") def __str__(self): return f"{self.lab.name} - {self.discovered_date}"

注册模型到 Admin 后台

打开lab/admin.py,输入代码:

from django.contrib import admin from .models import ( Laboratory, Semester, Teacher, LabTechnician, LabDuty, Course, Software, LabUsageRecord, LabMaintenance ) # 注册所有模型到后台 admin.site.register(Laboratory) admin.site.register(Semester) admin.site.register(Teacher) admin.site.register(LabTechnician) admin.site.register(LabDuty) admin.site.register(Course) admin.site.register(Software) admin.site.register(LabUsageRecord) admin.site.register(LabMaintenance)

执行数据库迁移

在终端运行以下命令,创建实验室相关的数据库表:

python manage.py makemigrations lab python manage.py migrate

重启服务器并验证

python manage.py runserver

分配人员权限

访问http://127.0.0.1:8000/admin,你会看到左侧菜单里出现了所有实验室相关的模型(Laboratory、Semester 等),同时回到用户组权限分配页面,输入lab就能看到对应的中文权限项了。

进入了 Lab_Technician 用户组的权限配置页面,接下来可以这样操作:

权限分配建议(按角色)

  • Lab_Technician(实验员)

推荐权限:Can add lab dutyCan change lab dutyCan view laboratoryCan view lab usage recordCan add lab maintenanceCan change lab maintenance

不建议给Can delete类权限,避免误删重要数据。

  • Teacher(教师)

推荐权限:Can view courseCan view laboratoryCan add lab usage recordCan change own lab usage record

  • Lab_Admin(管理员)

可以直接勾选所有lab应用的权限,进行全面管理

  1. 登录teacher_zhang的账号密码

这个界面说明你的权限分配完全成功了!

TEACHER_ZHANG的后台首页可以看到:

他只能看到LAB应用下的三个模块:Courses(查看)、Lab usage records(可添加)、Laboratories(查看)。

其他模块(如Lab dutysLab maintenances等)都被隐藏了,这正好符合教师角色的权限需求:

    • 可以查看课程和实验室信息
    • 可以提交实验室使用记录
    • 不能管理值班、维护等其他功能

这说明你之前的权限分配完全符合预期,系统已经可以正常使用了。

实验室管理系统的人员权限分配配置好了:

  • admin_li:属于Lab Admin组,拥有对lab应用的全部管理权限。
  • tech_li:属于Lab Technician组,负责值班和维护管理。
  • teacher_zhang:属于Teacher组,负责提交使用记录和查看信息。
  • niuke:超级管理员账号,拥有系统最高权限。
  1. 现在录入所有人员的用户权限
  2. 录入基础数据(用admin_li或超级用户登录)

按以下顺序录入,避免关联字段为空:

  1. Semesters(学期):如 “2026 年春季学期”。
  2. Teachers(教师):录入姓名、专业、联系方式(关联teacher_zhang等用户)。
  3. Lab technicians(实验员):录入姓名、工号(关联tech_li等用户)。
  4. Laboratories(实验室):录入房间号、座位数、安全等级、负责人(关联实验员)。
  5. Softwares(软件):录入实验室安装的软件名称、版本。
  6. Courses(课程):关联教师、对应实验室、所属学期。

验证所有角色的完整操作流程并运行

  • 教师(teacher_zhang):提交实验室使用申请保存成功。

  • 实验员(tech_li):查看/审核使用申请添加值班安排/维护记录保存成功。

  • 管理员(admin_li):修改/删除数据权限无异常。

只要各角色能完成对应操作,且无报错,就说明系统核心功能正常。

http://www.jsqmd.com/news/512542/

相关文章:

  • 【Linux】序列化与反序列化——网络计算器的实现
  • 告别漂移!手把手教你用LIO-SAM搭建自己的机器人定位系统(ROS1/ROS2实战)
  • 快速上手Whisper:基于预置镜像的语音识别Web服务搭建指南
  • 程序打不开 提示丢失mscomm32.ocx不要怕 教你免费修复
  • ImportError: libcudss.so.0: cannot open shared object file: No such file or directory
  • 安全驾驶 智在掌控|腾视科技ES06终端,为车辆运营赋能
  • 5步搞定MAI-UI-8B API调用:小白友好的实战教程
  • 如何提升学术交流效率:图文摘要的作用及制作要点
  • C++面试真题分享20260320
  • msjetoledb40.dll丢失损坏怎么办? 免费下载修复方法分享
  • Axios拦截器源码解析:从use方法到Promise链的完整执行流程
  • CCF-202412-T3缓存模拟90分
  • 巴西空运专线市场盘点:五大服务商助力中巴贸易 - 时事观察官
  • remove high frequency but keep low frequency
  • 20252918 2025-2026-2 《网络攻防实践》第1周作业
  • VMware 虚拟机安装--urbutun3种下载的镜像选择指南
  • Clawdbot优化升级:提升Qwen3:32B代理网关性能与稳定性的方法
  • 光伏PV三相并网逆变器MATLAB仿真模型:高效功率输出与稳定直流母线电压
  • RP2040嵌入式视觉平台:轻量级MIPI/并行摄像头采集方案
  • RP2350A开发板硬件设计与电源架构解析
  • msjint40.dll文件丢失不可怕 免费下载修复方法分享
  • 2026年上海房产律师推荐:房产继承分割难题高性价比律师与避坑指南 - 十大品牌推荐
  • 从Demo到实战:手把手教你定制Cartographer的Launch和Lua配置文件(Gazebo仿真版)
  • 手机号逆向查询QQ号:3步快速找回遗忘账号的终极指南
  • ESP32 cam (3)http协议 上传图片给电脑flask服务器 - MKT
  • 聊聊菲尔格林产品的优势,2026年干冰清洗机选购哪家好 - myqiye
  • IT 补丁管理的8大深坑,如何破解?
  • CNN架构解析:TranslateGemma模型中的卷积神经网络应用
  • 告别机械音!Qwen3-TTS实测:97ms低延迟生成真人级语音
  • 短视频种草新时代:传声港新媒体平台五大平台赋能品牌增长新引擎 - 博客湾