1. 项目背景与核心需求
在大学教学场景中,作业批改一直是让教师们头疼的环节。传统纸质作业或简单的邮件提交方式存在诸多痛点:作业版本混乱、批改痕迹难以保留、成绩统计费时费力。我曾在某高校计算机系担任助教时,每学期需要处理200多份编程作业,经常遇到学生重复提交不同版本、批注无法直观展示、成绩汇总需要手动录入Excel等问题。
这个Python+Django开发的学生作业批改提交系统小程序,正是为解决这些实际痛点而设计。系统核心功能包括:
- 学生端:作业在线提交、版本控制、批改结果查看
- 教师端:作业批注(支持代码高亮批改)、评分管理、成绩导出
- 管理端:课程/班级管理、用户权限控制
特别说明:系统采用Django框架的MTV模式开发,前端使用Bootstrap+JavaScript实现交互,数据库选用SQLite(教学场景)或MySQL(生产环境),完全适配从几十人到几百人的班级规模。
2. 技术选型与架构设计
2.1 为什么选择Django?
相比Flask等轻量级框架,Django自带的管理后台(admin)、ORM系统和用户认证模块,能大幅降低开发复杂度。例如:
python复制# 作业模型示例
class Assignment(models.Model):
title = models.CharField(max_length=200)
description = models.TextField()
deadline = models.DateTimeField()
course = models.ForeignKey(Course, on_delete=models.CASCADE)
# 自动生成管理界面
admin.site.register(Assignment)
仅需几行代码即可获得完整的数据管理界面,这对需要快速迭代的教育类应用至关重要。
2.2 前后端分离的权衡
虽然完全前后端分离(如Django+React)更现代,但考虑到:
- 教学场景下部署复杂度需要尽量低
- 批改系统对实时性要求不高
最终采用Django模板渲染方案,通过Ajax局部刷新实现关键交互。这种混合架构在保证用户体验的同时,使服务器只需单个Python环境即可运行。
2.3 数据库设计要点
核心实体关系图(简化版):
code复制User(AbstractUser) <- Student/Teacher
Course <- Assignment <- Submission -> Grade
特别注意:
- 使用Django的AbstractUser扩展自定义用户模型
- Submission模型需存储文件路径和提交历史
- Grade模型包含评分项和文字批注
3. 核心功能实现细节
3.1 作业提交与版本控制
关键实现代码:
python复制# models.py
class Submission(models.Model):
VERSION_CHOICES = [(i, f'v{i}') for i in range(1, 10)]
assignment = models.ForeignKey(Assignment, on_delete=models.CASCADE)
student = models.ForeignKey(Student, on_delete=models.CASCADE)
version = models.IntegerField(choices=VERSION_CHOICES)
file = models.FileField(upload_to=assignment_upload_path)
submitted_at = models.DateTimeField(auto_now_add=True)
def assignment_upload_path(instance, filename):
return f'assignments/{instance.assignment.id}/{instance.student.id}_{instance.version}{os.path.splitext(filename)[1]}'
文件存储采用"课程ID/学生ID_版本号"的命名规则,既避免重复又保留历史版本。前端通过Modal对话框实现新版提交时的确认提示。
3.2 批注系统实现
教师批改界面需要支持:
- 代码文件的高亮显示(使用highlight.js)
- 行级评论功能
- 评分项打分(如:代码规范20分、功能实现50分)
前端关键JavaScript代码:
javascript复制// 行号点击事件绑定
$('.code-line').click(function() {
const lineNum = $(this).data('line');
$('#comment-line').val(lineNum);
$('#comment-modal').modal('show');
});
3.3 成绩统计与导出
利用Django ORM的聚合功能实现:
python复制def course_grades(request, course_id):
from django.db.models import Avg
grades = Grade.objects.filter(
submission__assignment__course_id=course_id
).values(
'submission__student'
).annotate(
avg_score=Avg('score')
)
return render(request, 'grades.html', {'grades': grades})
导出Excel使用openpyxl库,支持按课程/班级筛选导出。
4. 部署实践与性能优化
4.1 开发环境配置建议
推荐使用:
- Python 3.8+(稳定且兼容性好)
- Virtualenv隔离环境
- VSCode配置:
json复制{ "python.pythonPath": "venv/bin/python", "python.linting.enabled": true }
4.2 生产环境部署
以宝塔面板为例的部署步骤:
- 安装Python项目管理器插件
- 创建Django项目,选择Python版本
- 配置静态文件路径(需收集static)
- 设置uWSGI或Gunicorn作为应用服务器
- 配置Nginx反向代理
踩坑提醒:Django的ALLOWED_HOSTS必须配置服务器IP/域名,DEBUG模式务必关闭!
4.3 性能优化技巧
-
数据库优化:
- 为常用查询字段添加索引
- 使用select_related/prefetch_related减少查询次数
python复制submissions = Submission.objects.select_related( 'student', 'assignment' ).filter(assignment__course=course) -
文件存储优化:
- 超过100人班级建议使用云存储(如阿里云OSS)
- 定期清理过期作业文件(Celery定时任务)
5. 扩展功能与二次开发
5.1 自动化批改集成
对于编程作业,可以扩展:
- 使用pytest运行测试用例自动评分
- 集成pylint进行代码规范检查
- 通过Docker隔离学生代码执行环境
5.2 微信小程序适配
通过DRF(Django REST Framework)提供API:
python复制class SubmissionViewSet(viewsets.ModelViewSet):
queryset = Submission.objects.all()
serializer_class = SubmissionSerializer
@action(detail=True, methods=['post'])
def submit(self, request, pk=None):
# 处理小程序端提交
5.3 多语言支持
利用Django的i18n功能:
-
在settings.py配置:
python复制LOCALE_PATHS = [os.path.join(BASE_DIR, 'locale')] LANGUAGE_CODE = 'zh-hans' -
在模板中使用:
html复制{% load i18n %} <h1>{% trans "Assignment Submission" %}</h1>
我在实际部署中发现,对于200人左右的班级,系统在基础配置的2核4G服务器上运行流畅。曾遇到高峰期提交时的性能问题,通过以下措施解决:
- 配置Celery异步处理文件上传
- 对批改页面添加缓存(@cache_page装饰器)
- 使用django-debug-toolbar定位慢查询
这个项目最值得分享的经验是:教育类系统一定要考虑极端使用场景——比如期末前一周的集中提交,以及教师可能同时批改多个班级作业的情况。提前做好压力测试能避免很多线上问题。
