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

基于Django实现的智慧校园考试系统-自动组卷算法实现

目录

  • 一.🦁 项目概述
    • 1.1 技术栈
    • 1.2 安装与运行
  • 二.🦁 演示系统流程
    • 2.1 管理员端
    • 2.2 学生端
    • 2.3 自动组卷算法实现
      • 1. 核心思路
      • 2. 随机与去重
  • 三.🦁 API接口文档
    • 3.1 用户管理
    • 3.2 题库管理
    • 3.3 考试管理
    • 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 安装与运行

  1. 克隆项目:gitcode、Githup
  2. 安装依赖:pip install -r requirements.txt
  3. 配置数据库:修改settings.py中的数据库配置
  4. 运行服务器:python manage.py runserver

二.🦁 演示系统流程

2.1 管理员端

  1. 登录

1
2. 仪表板
在这里插入图片描述
3. 用户管理
在这里插入图片描述
4. 题库管理
在这里插入图片描述
在这里插入图片描述
5. 考试管理
在这里插入图片描述
6. 试卷管理

  • 手动组卷
    在这里插入图片描述
  • 自动组卷
    在这里插入图片描述
  1. 成绩管理
    在这里插入图片描述

2.2 学生端

  1. 首页
    在这里插入图片描述
  2. 考试列表
    在这里插入图片描述
  3. 查看成绩
    在这里插入图片描述
  4. 个人中心
    在这里插入图片描述
  5. 考试页面
    在这里插入图片描述

在这里插入图片描述

2.3 自动组卷算法实现

1. 核心思路

  • 先创建一条考试记录 Exam (校验通过后保存)。
  • 对每个题型,分别按难度从题库查询题目列表。
  • 如果某个难度的题数不够,直接返回错误。
  • 若题数足够,就用 random.sample 在题目列表里随机抽取指定数量。
  • 把抽到的题目逐条保存成 ExamQuestion ,与该考试关联。
  • 最后返回这次考试的基本信息和总题数。

2. 随机与去重

  • random.sample 在同一题型+难度范围内不会重复抽同一题
  • 不会出现跨题型重复,因为查询条件包含 question_type
  • 如果 question_types 传入有重复值,会去重
@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_countif medium_count > 0:selected_questions.extend(random.sample(medium_questions, medium_count))total_questions += medium_countif 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).dataexam_data['question_count'] = total_questionsreturn Response({"message": f"成功自动生成试卷,包含 {total_questions} 道题目(每种题型:简单{easy_count}道,中等{medium_count}道,困难{hard_count}道)","exam": exam_data}, status=status.HTTP_201_CREATED)

三.🦁 API接口文档

3.1 用户管理

  1. 注册用户
  • URL: /api/users/register/

  • 方法: POST

  • 请求体:

    {"username": "用户名","password": "密码","role": "admin或student"
    }
    
  • 响应:

    {"user_id": 1,"username": "用户名","role": "admin或student","created_at": "创建时间"
    }
    
  1. 用户登录
  • URL: /api/users/login/

  • 方法: POST

  • 请求体:

    {"username": "用户名","password": "密码"
    }
    
  • 响应:

    {"token": "JWT令牌","user": {"user_id": 1,"username": "用户名","role": "admin或student"}
    }
    
  1. 获取当前用户信息
  • URL: /api/users/current/

  • 方法: GET

  • 请求头: Authorization: Bearer {token}

  • 响应:

    {"user_id": 1,"username": "用户名","role": "admin或student","created_at": "创建时间"
    }
    
  1. 获取所有用户
  • URL: /api/users/

  • 方法: GET

  • 请求头: Authorization: Bearer {token}

  • 响应:

    [{"user_id": 1,"username": "用户名","role": "admin或student","created_at": "创建时间"}
    ]
    
  1. 获取特定用户
  • URL: /api/users/{user_id}/

  • 方法: GET

  • 请求头: Authorization: Bearer {token}

  • 响应:

    {"user_id": 1,"username": "用户名","role": "admin或student","created_at": "创建时间"
    }
    
  1. 更新用户
  • URL: /api/users/{user_id}/update/

  • 方法: PUT

  • 请求头: Authorization: Bearer {token}

  • 请求体:

    {"username": "新用户名","password": "新密码","role": "新角色"
    }
    
  • 响应:

    {"user_id": 1,"username": "新用户名","role": "新角色","created_at": "创建时间"
    }
    
  1. 删除用户
  • URL: /api/users/{user_id}/delete/
  • 方法: DELETE
  • 请求头: Authorization: Bearer {token}
  • 响应: 204 No Content

3.2 题库管理

  1. 添加题目
  • URL: /api/questions/add/

  • 方法: POST

  • 请求头: Authorization: Bearer {token}

  • 请求体:

    {"content": "题目内容","question_type": "choice/true_false/fill_in_blank/essay","difficulty_level": "easy/medium/hard"
    }
    
  • 响应:

    {"question_id": 1,"content": "题目内容","question_type": "choice/true_false/fill_in_blank/essay","difficulty_level": "easy/medium/hard","created_at": "创建时间"
    }
    
  1. 获取所有题目
  • URL: /api/questions/

  • 方法: GET

  • 请求头: Authorization: Bearer {token}

  • 响应:

    [{"question_id": 1,"content": "题目内容","question_type": "choice/true_false/fill_in_blank/essay","difficulty_level": "easy/medium/hard","created_at": "创建时间"}
    ]
    
  1. 获取特定题目
  • URL: /api/questions/get/{question_id}/

  • 方法: GET

  • 请求头: Authorization: Bearer {token}

  • 响应:

    {"question_id": 1,"content": "题目内容","question_type": "choice/true_false/fill_in_blank/essay","difficulty_level": "easy/medium/hard","created_at": "创建时间"
    }
    
  1. 更新题目
  • URL: /api/questions/update/{question_id}/

  • 方法: PUT

  • 请求头: Authorization: Bearer {token}

  • 请求体:

    {"content": "新题目内容","question_type": "新题目类型","difficulty_level": "新难度级别"
    }
    
  • 响应:

    {"question_id": 1,"content": "新题目内容","question_type": "新题目类型","difficulty_level": "新难度级别","created_at": "创建时间"
    }
    
  1. 删除题目
  • URL: /api/questions/delete/{question_id}/
  • 方法: DELETE
  • 请求头: Authorization: Bearer {token}
  • 响应: 204 No Content

3.3 考试管理

  1. 创建考试
  • URL: /api/exams/create/

  • 方法: POST

  • 请求头: Authorization: Bearer {token}

  • 请求体:

    {"exam_name": "考试名称","start_time": "开始时间","end_time": "结束时间","duration": 120
    }
    
  • 响应:

    {"exam_id": 1,"exam_name": "考试名称","start_time": "开始时间","end_time": "结束时间","duration": 120,"created_at": "创建时间"
    }
    
  1. 获取所有考试
  • URL: /api/exams/

  • 方法: GET

  • 请求头: Authorization: Bearer {token}

  • 响应:

    [{"exam_id": 1,"exam_name": "考试名称","start_time": "开始时间","end_time": "结束时间","duration": 120,"created_at": "创建时间"}
    ]
    
  1. 获取特定考试
  • URL: /api/exams/get/{exam_id}/

  • 方法: GET

  • 请求头: Authorization: Bearer {token}

  • 响应:

    {"exam_id": 1,"exam_name": "考试名称","start_time": "开始时间","end_time": "结束时间","duration": 120,"created_at": "创建时间"
    }
    
  1. 更新考试
  • URL: /api/exams/update/{exam_id}/

  • 方法: PUT

  • 请求头: Authorization: Bearer {token}

  • 请求体:

    {"exam_name": "新考试名称","start_time": "新开始时间","end_time": "新结束时间","duration": 150
    }
    
  • 响应:

    {"exam_id": 1,"exam_name": "新考试名称","start_time": "新开始时间","end_time": "新结束时间","duration": 150,"created_at": "创建时间"
    }
    
  1. 删除考试
  • URL: /api/exams/delete/{exam_id}/
  • 方法: DELETE
  • 请求头: Authorization: Bearer {token}
  • 响应: 204 No Content
  1. 添加题目到考试
  • URL: /api/exams/add_question/

  • 方法: POST

  • 请求头: Authorization: Bearer {token}

  • 请求体:

    {"exam": 1,"question": 1
    }
    
  • 响应:

    {"exam_question_id": 1,"exam": 1,"question": 1,"question_detail": {"question_id": 1,"content": "题目内容","question_type": "题目类型","difficulty_level": "难度级别","created_at": "创建时间"}
    }
    
  1. 获取考试的所有题目
  • URL: /api/exams/questions/{exam_id}/

  • 方法: GET

  • 请求头: Authorization: Bearer {token}

  • 响应:

    [{"exam_question_id": 1,"exam": 1,"question": 1,"question_detail": {"question_id": 1,"content": "题目内容","question_type": "题目类型","difficulty_level": "难度级别","created_at": "创建时间"}}
    ]
    
  1. 自动组卷
  • URL: /api/exams/generate_paper/

  • 方法: POST

  • 请求头: Authorization: Bearer {token}

  • 请求体:

    {"exam_id": 1,"easy_count": 5,"medium_count": 3,"hard_count": 2
    }
    
  • 响应:

    {"message": "成功添加 10 道题目到考试"
    }
    

3.4 成绩管理

  1. 添加成绩
  • URL: /api/scores/add/

  • 方法: POST

  • 请求头: Authorization: Bearer {token}

  • 请求体:

    {"user": 1,"exam": 1,"score": 85
    }
    
  • 响应:

    {"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": "创建时间"}
    }
    
  1. 获取用户成绩
  • URL: /api/scores/user/{user_id}/

  • 方法: GET

  • 请求头: Authorization: Bearer {token}

  • 响应:

    [{"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": "创建时间"}}
    ]
    
  1. 获取考试成绩
  • URL: /api/scores/exam/{exam_id}/

  • 方法: GET

  • 请求头: Authorization: Bearer {token}

  • 响应:

    [{"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": "创建时间"}}
    ]
    
  1. 获取历史考试记录
  • URL: /api/scores/history/{user_id}/

  • 方法: GET

  • 请求头: Authorization: Bearer {token}

  • 响应:

    [{"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咱们顶峰相见!

http://www.dtcms.com/a/597362.html

相关文章:

  • Java垃圾收集器全解:从Serial到G1的进化之旅
  • 如何免费建造网站苏州有哪些做网站公司
  • 基于IMM交互式多模型卡尔曼滤波的目标位置和速度估计matlab仿真
  • 微信_网站提成方案点做南昌网站建设推广专家
  • Phoenix+Hbase和Doris两个方案如何选择,能不能拿Doris完全替代Phoenix+Hbase?有什么难点?
  • 免费网站大全下载全球速卖通卖家注册
  • 生物信息学 (101计划核心教程)Chapter4
  • 【疑难解答】@Value 注解不生效的原因
  • 【题解】【深基2.例2】英文字母
  • 关于建设殡葬网站的报告范文wordpress免费模板小而美
  • ssm项目,邮箱验证码
  • 多网卡同网段 IP 引发的 ARP Flux
  • 机器学习日报16
  • 11月份运维面试题
  • H100服务器维修“病历卡”:五大常见故障现象与根源分析
  • 9. Linux-riscv内存管理41-46问
  • 用mcu做灯光效果网站大连金州新区规划建设局网站
  • React 实战: Todo 应用学习小结
  • 网站性能优化方案网络设计及网络设计文档
  • 香港科技大学广州|可持续能源与环境学域博士招生宣讲会—兰州大学专场
  • 下午察:当机器人变得太像人
  • 青海城乡与建设厅网站个人简历简短范文
  • 黑马JAVAWeb -Vue工程化-API风格 - 组合式API
  • ubuntu更新nvidia显卡驱动
  • React Native 自建 JS Bundle OTA 更新系统:从零到一的完整实现与踩坑记录
  • 珠海建设网站公司代刷网站只做软件下载
  • 磐安县建设局网站甘肃营销型网站制作
  • UEC++ 如何知道有哪些UComponent?
  • 创建轻量级 3D 资产 - Three.js 中的 GLTF 案例
  • Android 主线程性能优化实战:从 90% 降至 13%