目录
- [一.🦁 项目概述](#一.🦁 项目概述)
-
- [1.1 技术栈](#1.1 技术栈)
- [1.2 安装与运行](#1.2 安装与运行)
- [二.🦁 演示系统流程](#二.🦁 演示系统流程)
-
- [2.1 管理员端](#2.1 管理员端)
- [2.2 学生端](#2.2 学生端)
- [2.3 自动组卷算法实现](#2.3 自动组卷算法实现)
-
- [1. 核心思路](#1. 核心思路)
- [2. 随机与去重](#2. 随机与去重)
- [三.🦁 API接口文档](#三.🦁 API接口文档)
-
- [3.1 用户管理](#3.1 用户管理)
- [3.2 题库管理](#3.2 题库管理)
- [3.3 考试管理](#3.3 考试管理)
- [3.4 成绩管理](#3.4 成绩管理)
项目定制业务:前端、后端(Python、Java、C#、PHP)、算法(深度学习、机器学习)、大数据(Hadoop、hive、spark)、小程序等项目 ,
无论是商用 还是学校项目(毕业设计、课程设计等) ,都可咨询,价格合理,服务周全!
如果你有需要,添加vx:732708009
一.🦁 项目概述
基于Django开发的智慧校园考试系统后端API,采用前后端分离架构,提供RESTful风格接口,涵盖用户管理、题库管理、考试管理和成绩管理等核心功能模块。首先,用户管理模块支持学生和管理员两种角色,提供用户注册与登录(JWT认证)、个人信息管理。其次,题库管理模块支持多种试题类型,如单选题、判断题、填空题、简答题,实现试题的CRUD操作、智能组卷算法、试题分类标签管理及难度系数设置。然后,考试管理模块涵盖考试创建、考生报名与审核、在线考试等功能,提供考试场次管理。最后,成绩管理模块实现了自动评分(客观题)、成绩统计分析、提供成绩查询、成绩分布可视化以及错题分析和历史成绩对比等功能。
1.1 技术栈
- Python 3.8+
- Django 4.2
- Django REST Framework
- MySQL
1.2 安装与运行
- 克隆项目:gitcode、Githup
- 安装依赖:
pip install -r requirements.txt - 配置数据库:修改
settings.py中的数据库配置 - 运行服务器:
python manage.py runserver
二.🦁 演示系统流程
2.1 管理员端
- 登录

-
仪表板

-
用户管理

-
题库管理


-
考试管理

-
试卷管理
- 手动组卷

- 自动组卷

- 成绩管理

2.2 学生端
- 首页

- 考试列表

- 查看成绩

- 个人中心

- 考试页面


2.3 自动组卷算法实现
1. 核心思路
- 先创建一条考试记录 Exam (校验通过后保存)。
- 对每个题型,分别按难度从题库查询题目列表。
- 如果某个难度的题数不够,直接返回错误。
- 若题数足够,就用 random.sample 在题目列表里随机抽取指定数量。
- 把抽到的题目逐条保存成 ExamQuestion ,与该考试关联。
- 最后返回这次考试的基本信息和总题数。
2. 随机与去重
- random.sample 在同一题型+难度范围内不会重复抽同一题
- 不会出现跨题型重复,因为查询条件包含 question_type
- 如果 question_types 传入有重复值,会去重
python
@api_view(['POST'])
@permission_classes([IsAuthenticated])
def generate_exam_paper(request):
# 获取考试基本信息
exam_name = request.data.get('exam_name')
start_time = request.data.get('start_time')
end_time = request.data.get('end_time')
duration = request.data.get('duration')
# 获取题目配置
easy_count = int(request.data.get('easy_count', 0))
medium_count = int(request.data.get('medium_count', 0))
hard_count = int(request.data.get('hard_count', 0))
question_types = request.data.get('question_types', [])
# 创建考试
exam_data = {
'exam_name': exam_name,
'start_time': start_time,
'end_time': end_time,
'duration': duration
}
serializer = ExamSerializer(data=exam_data)
if not serializer.is_valid():
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
exam = serializer.save()
# 为每种题型按难度分布生成题目
selected_questions = []
total_questions = 0
# 遍历每种题型
for question_type in question_types:
# 获取当前题型不同难度的题目
easy_questions = list(Question.objects.filter(
difficulty_level='easy',
question_type=question_type
))
medium_questions = list(Question.objects.filter(
difficulty_level='medium',
question_type=question_type
))
hard_questions = list(Question.objects.filter(
difficulty_level='hard',
question_type=question_type
))
# 检查当前题型的题目数量是否足够
if easy_count > 0 and len(easy_questions) < easy_count:
return Response({
"error": f"{question_type}类型的简单题目不足,需要 {easy_count} 道,实际只有 {len(easy_questions)} 道"
}, status=status.HTTP_400_BAD_REQUEST)
if medium_count > 0 and len(medium_questions) < medium_count:
return Response({
"error": f"{question_type}类型的中等题目不足,需要 {medium_count} 道,实际只有 {len(medium_questions)} 道"
}, status=status.HTTP_400_BAD_REQUEST)
if hard_count > 0 and len(hard_questions) < hard_count:
return Response({
"error": f"{question_type}类型的困难题目不足,需要 {hard_count} 道,实际只有 {len(hard_questions)} 道"
}, status=status.HTTP_400_BAD_REQUEST)
# 为当前题型随机选择题目
if easy_count > 0:
selected_questions.extend(random.sample(easy_questions, easy_count))
total_questions += easy_count
if medium_count > 0:
selected_questions.extend(random.sample(medium_questions, medium_count))
total_questions += medium_count
if hard_count > 0:
selected_questions.extend(random.sample(hard_questions, hard_count))
total_questions += hard_count
# 添加题目到考试
for question in selected_questions:
ExamQuestion.objects.create(exam=exam, question=question)
# 返回包含题目数量的考试信息
exam_data = ExamSerializer(exam).data
exam_data['question_count'] = total_questions
return Response({
"message": f"成功自动生成试卷,包含 {total_questions} 道题目(每种题型:简单{easy_count}道,中等{medium_count}道,困难{hard_count}道)",
"exam": exam_data
}, status=status.HTTP_201_CREATED)
三.🦁 API接口文档
3.1 用户管理
- 注册用户
-
URL:
/api/users/register/ -
方法: POST
-
请求体:
json{ "username": "用户名", "password": "密码", "role": "admin或student" } -
响应:
json{ "user_id": 1, "username": "用户名", "role": "admin或student", "created_at": "创建时间" }
- 用户登录
-
URL:
/api/users/login/ -
方法: POST
-
请求体:
json{ "username": "用户名", "password": "密码" } -
响应:
json{ "token": "JWT令牌", "user": { "user_id": 1, "username": "用户名", "role": "admin或student" } }
- 获取当前用户信息
-
URL:
/api/users/current/ -
方法: GET
-
请求头:
Authorization: Bearer {token} -
响应:
json{ "user_id": 1, "username": "用户名", "role": "admin或student", "created_at": "创建时间" }
- 获取所有用户
-
URL:
/api/users/ -
方法: GET
-
请求头:
Authorization: Bearer {token} -
响应:
json[ { "user_id": 1, "username": "用户名", "role": "admin或student", "created_at": "创建时间" } ]
- 获取特定用户
-
URL:
/api/users/{user_id}/ -
方法: GET
-
请求头:
Authorization: Bearer {token} -
响应:
json{ "user_id": 1, "username": "用户名", "role": "admin或student", "created_at": "创建时间" }
- 更新用户
-
URL:
/api/users/{user_id}/update/ -
方法: PUT
-
请求头:
Authorization: Bearer {token} -
请求体:
json{ "username": "新用户名", "password": "新密码", "role": "新角色" } -
响应:
json{ "user_id": 1, "username": "新用户名", "role": "新角色", "created_at": "创建时间" }
- 删除用户
- URL:
/api/users/{user_id}/delete/ - 方法: DELETE
- 请求头:
Authorization: Bearer {token} - 响应: 204 No Content
3.2 题库管理
- 添加题目
-
URL:
/api/questions/add/ -
方法: POST
-
请求头:
Authorization: Bearer {token} -
请求体:
json{ "content": "题目内容", "question_type": "choice/true_false/fill_in_blank/essay", "difficulty_level": "easy/medium/hard" } -
响应:
json{ "question_id": 1, "content": "题目内容", "question_type": "choice/true_false/fill_in_blank/essay", "difficulty_level": "easy/medium/hard", "created_at": "创建时间" }
- 获取所有题目
-
URL:
/api/questions/ -
方法: GET
-
请求头:
Authorization: Bearer {token} -
响应:
json[ { "question_id": 1, "content": "题目内容", "question_type": "choice/true_false/fill_in_blank/essay", "difficulty_level": "easy/medium/hard", "created_at": "创建时间" } ]
- 获取特定题目
-
URL:
/api/questions/get/{question_id}/ -
方法: GET
-
请求头:
Authorization: Bearer {token} -
响应:
json{ "question_id": 1, "content": "题目内容", "question_type": "choice/true_false/fill_in_blank/essay", "difficulty_level": "easy/medium/hard", "created_at": "创建时间" }
- 更新题目
-
URL:
/api/questions/update/{question_id}/ -
方法: PUT
-
请求头:
Authorization: Bearer {token} -
请求体:
json{ "content": "新题目内容", "question_type": "新题目类型", "difficulty_level": "新难度级别" } -
响应:
json{ "question_id": 1, "content": "新题目内容", "question_type": "新题目类型", "difficulty_level": "新难度级别", "created_at": "创建时间" }
- 删除题目
- URL:
/api/questions/delete/{question_id}/ - 方法: DELETE
- 请求头:
Authorization: Bearer {token} - 响应: 204 No Content
3.3 考试管理
- 创建考试
-
URL:
/api/exams/create/ -
方法: POST
-
请求头:
Authorization: Bearer {token} -
请求体:
json{ "exam_name": "考试名称", "start_time": "开始时间", "end_time": "结束时间", "duration": 120 } -
响应:
json{ "exam_id": 1, "exam_name": "考试名称", "start_time": "开始时间", "end_time": "结束时间", "duration": 120, "created_at": "创建时间" }
- 获取所有考试
-
URL:
/api/exams/ -
方法: GET
-
请求头:
Authorization: Bearer {token} -
响应:
json[ { "exam_id": 1, "exam_name": "考试名称", "start_time": "开始时间", "end_time": "结束时间", "duration": 120, "created_at": "创建时间" } ]
- 获取特定考试
-
URL:
/api/exams/get/{exam_id}/ -
方法: GET
-
请求头:
Authorization: Bearer {token} -
响应:
json{ "exam_id": 1, "exam_name": "考试名称", "start_time": "开始时间", "end_time": "结束时间", "duration": 120, "created_at": "创建时间" }
- 更新考试
-
URL:
/api/exams/update/{exam_id}/ -
方法: PUT
-
请求头:
Authorization: Bearer {token} -
请求体:
json{ "exam_name": "新考试名称", "start_time": "新开始时间", "end_time": "新结束时间", "duration": 150 } -
响应:
json{ "exam_id": 1, "exam_name": "新考试名称", "start_time": "新开始时间", "end_time": "新结束时间", "duration": 150, "created_at": "创建时间" }
- 删除考试
- URL:
/api/exams/delete/{exam_id}/ - 方法: DELETE
- 请求头:
Authorization: Bearer {token} - 响应: 204 No Content
- 添加题目到考试
-
URL:
/api/exams/add_question/ -
方法: POST
-
请求头:
Authorization: Bearer {token} -
请求体:
json{ "exam": 1, "question": 1 } -
响应:
json{ "exam_question_id": 1, "exam": 1, "question": 1, "question_detail": { "question_id": 1, "content": "题目内容", "question_type": "题目类型", "difficulty_level": "难度级别", "created_at": "创建时间" } }
- 获取考试的所有题目
-
URL:
/api/exams/questions/{exam_id}/ -
方法: GET
-
请求头:
Authorization: Bearer {token} -
响应:
json[ { "exam_question_id": 1, "exam": 1, "question": 1, "question_detail": { "question_id": 1, "content": "题目内容", "question_type": "题目类型", "difficulty_level": "难度级别", "created_at": "创建时间" } } ]
- 自动组卷
-
URL:
/api/exams/generate_paper/ -
方法: POST
-
请求头:
Authorization: Bearer {token} -
请求体:
json{ "exam_id": 1, "easy_count": 5, "medium_count": 3, "hard_count": 2 } -
响应:
json{ "message": "成功添加 10 道题目到考试" }
3.4 成绩管理
- 添加成绩
-
URL:
/api/scores/add/ -
方法: POST
-
请求头:
Authorization: Bearer {token} -
请求体:
json{ "user": 1, "exam": 1, "score": 85 } -
响应:
json{ "score_id": 1, "user": 1, "exam": 1, "score": 85, "created_at": "创建时间", "user_detail": { "user_id": 1, "username": "用户名", "role": "角色", "created_at": "创建时间" }, "exam_detail": { "exam_id": 1, "exam_name": "考试名称", "start_time": "开始时间", "end_time": "结束时间", "duration": 120, "created_at": "创建时间" } }
- 获取用户成绩
-
URL:
/api/scores/user/{user_id}/ -
方法: GET
-
请求头:
Authorization: Bearer {token} -
响应:
json[ { "score_id": 1, "user": 1, "exam": 1, "score": 85, "created_at": "创建时间", "user_detail": { "user_id": 1, "username": "用户名", "role": "角色", "created_at": "创建时间" }, "exam_detail": { "exam_id": 1, "exam_name": "考试名称", "start_time": "开始时间", "end_time": "结束时间", "duration": 120, "created_at": "创建时间" } } ]
- 获取考试成绩
-
URL:
/api/scores/exam/{exam_id}/ -
方法: GET
-
请求头:
Authorization: Bearer {token} -
响应:
json[ { "score_id": 1, "user": 1, "exam": 1, "score": 85, "created_at": "创建时间", "user_detail": { "user_id": 1, "username": "用户名", "role": "角色", "created_at": "创建时间" }, "exam_detail": { "exam_id": 1, "exam_name": "考试名称", "start_time": "开始时间", "end_time": "结束时间", "duration": 120, "created_at": "创建时间" } } ]
- 获取历史考试记录
-
URL:
/api/scores/history/{user_id}/ -
方法: GET
-
请求头:
Authorization: Bearer {token} -
响应:
json[ { "history_id": 1, "user": 1, "exam": 1, "score": 85, "completed_at": "完成时间", "user_detail": { "user_id": 1, "username": "用户名", "role": "角色", "created_at": "创建时间" }, "exam_detail": { "exam_id": 1, "exam_name": "考试名称", "start_time": "开始时间", "end_time": "结束时间", "duration": 120, "created_at": "创建时间" } } ]

🦁 其它优质专栏推荐 🦁
🌟《Java核心系列(修炼内功,无上心法)》: 主要是JDK源码的核心讲解,几乎每篇文章都过万字,让你详细掌握每一个知识点!
🌟 《springBoot 源码剥析核心系列》:一些场景的Springboot源码剥析以及常用Springboot相关知识点解读
欢迎加入狮子的社区 :『Lion-编程进阶之路』,日常收录优质好文
更多文章可持续关注上方🦁的博客,2025咱们顶峰相见!