从0到1搭建教务系统:选课与成绩录入模块源码解析

在高校数字化校园建设中,教务管理系统是核心枢纽,而选课与成绩录入模块则是直接关系到学生学业体验的关键功能。本文将从源码层面,拆解这两个模块的核心逻辑与实现思路,帮助开发者快速理解并搭建类似功能。


🎯 选课模块核心源码逻辑

选课模块的核心需求是实现学生自主选择课程、系统实时校验冲突并锁定名额,同时支持管理员后台配置课程容量与选课规则。以下是关键代码模块的解析:

1. 课程数据模型设计

Python
复制
from django.db import models
from django.contrib.auth.models import User

class Course(models.Model):
course_id = models.CharField(max_length=20, unique=True, verbose_name="课程编号")
name = models.CharField(max_length=100, verbose_name="课程名称")
teacher = models.ForeignKey(User, on_delete=models.CASCADE, related_name="taught_courses", verbose_name="授课教师")
credit = models.FloatField(verbose_name="学分")
capacity = models.IntegerField(verbose_name="选课容量")
enrolled_count = models.IntegerField(default=0, verbose_name="已选人数")
start_time = models.DateTimeField(verbose_name="开课时间")
end_time = models.DateTimeField(verbose_name="结课时间")

def __str__(self):
return f"{self.course_id} - {self.name}"

class StudentCourse(models.Model):
student = models.ForeignKey(User, on_delete=models.CASCADE, related_name="selected_courses", verbose_name="学生")
course = models.ForeignKey(Course, on_delete=models.CASCADE, related_name="enrolled_students", verbose_name="课程")
select_time = models.DateTimeField(auto_now_add=True, verbose_name="选课时间")

class Meta:
unique_together = ("student", "course")

代码解析

  • 采用Django ORM设计数据模型,通过Course类存储课程基础信息,StudentCourse类记录学生选课关联关系
  • 通过unique_together约束确保学生无法重复选择同一门课程
  • 实时维护enrolled_count字段,避免超容量选课

2. 选课冲突校验逻辑

Python
复制
from django.utils import timezone
from django.db.models import Q

def check_time_conflict(student, new_course):
# 获取学生已选课程的时间范围
existing_courses = StudentCourse.objects.filter(student=student).values_list('course__start_time', 'course__end_time')

for start, end in existing_courses:
# 时间冲突判断:新课程时间与已有课程时间存在重叠
if (new_course.start_time < end) and (new_course.end_time > start):
return True
return False

def select_course(student, course_id):
try:
course = Course.objects.get(course_id=course_id)
except Course.DoesNotExist:
return "课程不存在"

# 校验课程容量
if course.enrolled_count >= course.capacity:
return "课程已满员"

# 校验时间冲突
if check_time_conflict(student, course):
return "选课时间冲突"

# 原子操作:避免并发选课导致超容
with transaction.atomic():
course.enrolled_count += 1
course.save()
StudentCourse.objects.create(student=student, course=course)

return "选课成功"

代码解析

  • 通过check_time_conflict函数判断新选课程与已选课程的时间是否重叠
  • 采用数据库事务(transaction.atomic())确保选课操作的原子性,解决并发场景下的超容问题
  • 分层校验逻辑:依次检查课程存在性、容量限制、时间冲突,最后执行选课操作

📝 成绩录入模块核心源码逻辑

成绩录入模块需要支持教师批量录入成绩、系统自动计算绩点,同时提供学生成绩查询与申诉入口。以下是核心功能的实现代码:

1. 成绩数据模型设计

Python
复制
class Grade(models.Model):
student = models.ForeignKey(User, on_delete=models.CASCADE, related_name="grades", verbose_name="学生")
course = models.ForeignKey(Course, on_delete=models.CASCADE, related_name="grades", verbose_name="课程")
score = models.FloatField(verbose_name="成绩")
gpa = models.FloatField(blank=True, null=True, verbose_name="绩点")
submit_time = models.DateTimeField(auto_now_add=True, verbose_name="录入时间")
updated_time = models.DateTimeField(auto_now=True, verbose_name="更新时间")

class Meta:
unique_together = ("student", "course")

def save(self, *args, **kwargs):
# 自动计算绩点
if self.score >= 90:
self.gpa = 4.0
elif self.score >= 85:
self.gpa = 3.7
elif self.score >= 82:
self.gpa = 3.3
elif self.score >= 78:
self.gpa = 3.0
elif self.score >= 75:
self.gpa = 2.7
elif self.score >= 72:
self.gpa = 2.3
elif self.score >= 68:
self.gpa = 2.0
elif self.score >= 64:
self.gpa = 1.5
elif self.score >= 60:
self.gpa = 1.0
else:
self.gpa = 0.0
super().save(*args, **kwargs)

代码解析

  • 通过重写save方法,在成绩录入时自动计算绩点,减少业务逻辑的冗余
  • 采用unique_together约束确保同一学生同一课程只能有一条成绩记录
  • 记录成绩的提交与更新时间,便于追溯成绩修改历史

2. 教师批量录入成绩功能

Python
复制
import pandas as pd
from django.http import JsonResponse

def batch_import_grades(request, course_id):
if request.method != "POST":
return JsonResponse({"status": "error", "message": "仅支持POST请求"})

try:
course = Course.objects.get(course_id=course_id)
except Course.DoesNotExist:
return JsonResponse({"status": "error", "message": "课程不存在"})

# 验证当前用户是否为课程教师
if request.user != course.teacher:
return JsonResponse({"status": "error", "message": "无权限录入该课程成绩"})

file = request.FILES.get("grade_file")
if not file:
return JsonResponse({"status": "error", "message": "请上传成绩文件"})

# 读取Excel文件
df = pd.read_excel(file)
required_columns = ["学号", "成绩"]
if not all(col in df.columns for col in required_columns):
return JsonResponse({"status": "error", "message": "文件格式错误,需包含'学号'和'成绩'列"})

success_count = 0
error_count = 0
error_messages = []

for index, row in df.iterrows():
student_id = row["学号"]
score = row["成绩"]

try:
student = User.objects.get(username=student_id)
# 检查学生是否选过该课程
if not StudentCourse.objects.filter(student=student, course=course).exists():
error_messages.append(f"行{index+2}: 学生{student_id}未选该课程")
error_count += 1
continue

# 更新或创建成绩记录
grade, created = Grade.objects.update_or_create(
student=student,
course=course,
defaults={"score": score}
)
success_count += 1
except User.DoesNotExist:
error_messages.append(f"行{index+2}: 学生{student_id}不存在")
error_count += 1

return JsonResponse({
"status": "success",
"success_count": success_count,
"error_count": error_count,
"error_messages": error_messages
})

代码解析

  • 支持教师上传Excel文件批量录入成绩,提高工作效率
  • 多层权限校验:验证教师身份、学生选课状态,确保成绩录入的合法性
  • 详细的错误反馈机制,帮助教师快速定位并修正录入错误

🚀 性能优化与安全建议

  1. 选课模块优化
    • 采用Redis缓存热门课程的剩余容量,减少数据库查询压力
    • 对选课请求进行限流,防止恶意刷课行为
    • 实现选课排队机制,在课程容量满额时允许学生排队等待退课名额
  2. 成绩模块安全
    • 对成绩录入接口添加操作日志,记录每次成绩修改的人员与时间
    • 学生成绩查询接口采用加密传输,防止数据泄露
    • 实现成绩申诉流程,支持学生提交申诉申请,管理员后台审核处理

💡 总结

选课与成绩录入模块作为教务管理系统的核心功能,其源码设计需要兼顾业务逻辑的严谨性与用户体验的流畅性。通过本文的源码解析,开发者可以快速理解这两个模块的核心实现思路,并根据实际需求进行定制化开发。在实际项目中,还需要结合学校的具体业务规则,进一步完善系统的功能与性能。

购买须知/免责声明
1.本文部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责。
2.若您需要商业运营或用于其他商业活动,请您购买正版授权并合法使用。
3.如果本站有侵犯、不妥之处的资源,请在网站右边客服联系我们。将会第一时间解决!
4.本站所有内容均由互联网收集整理、网友上传,仅供大家参考、学习,不存在任何商业目的与商业用途。
5.本站提供的所有资源仅供参考学习使用,版权归原著所有,禁止下载本站资源参与商业和非法行为,请在24小时之内自行删除!
6.不保证任何源码框架的完整性。
7.侵权联系邮箱:aliyun6168@gail.com / aliyun666888@gail.com
8.若您最终确认购买,则视为您100%认同并接受以上所述全部内容。

小璐导航资源站 技术社区 从0到1搭建教务系统:选课与成绩录入模块源码解析 https://o789.cn/25348.html

相关文章

猜你喜欢