手机版
您的当前位置: 诚达文秘网 > 范文大全 > 学习强国 > 基于Django编程学习辅助系统设计与实现

基于Django编程学习辅助系统设计与实现

来源:学习强国 时间:2023-06-01 09:25:05

基于Django的编程学习辅助系统的设计与实现 Design and Implementation of Programming Learning Assistant System Based on Django 摘要 计算机编程的学习不仅注重书本的阅读,更离不开个人的动手实践。编写代码即动手实践,是将知识具体化的过程。而编程能力的评定包括编写代码的速度、质量和总量等三个维度,其中总量是最直观和具体的。

作者针对广东东软学院本科计算机相关专业的学生进行调研,发现由于学生的代码零散地分布于课程作业、在线判题系统平台和个人实践项目中,导致学生和老师都难以获取代码总量这个指标。为了解决这个问题,作者设计和开发了基于Django的编程学习辅助在线系统,取名积码。

积码系统以代码量统计分析为核心,将作业管理、索引在线判题系统平台、学习交流和共享资源进行了整合。学生和授课老师可以通过积码系统,记录学生在大学本科四年内完成的实践成果,获得代码量统计报告,监控学生的学习情况,让拿取资源更加便利,以达到辅助编程学习的效果。

关键词:
Django,web系统平台,代码量统计报告,监控学习情况,编程学习辅助 Abstract The study of computer programming not only pays attention to the reading of books, but also cannot be separated from personal hands-on practice. Hands-on practice is writing code, which is the process of materializing knowledge. The evaluation of programming ability includes three dimensions, such as the speed, quality, and total amount of code written. The total amount is the most intuitive and specific. The author conducted a survey of undergraduates majoring in computer science at Guangdong Neusoft University, and found that students 'and teachers' difficulty in obtaining the indicator of the total code is due to the scattered distribution of student codes in coursework, online problem determination system platforms, and personal practice projects. In order to solve this problem, the author designed and developed an online system based on Django for programming and learning, named JiCode. The JiCode system is based on the statistical analysis of code amount, and integrates job management, indexing online problem determination system platform, learning communication and shared resources. Students and lecturers can use the JiCode system to record the practical results of students completed within four years of college, obtain code analysis reports, monitor student learning, and make it easier to obtain resources to achieve the effect of assisted programming learning. Key words: Django, Web System Platform, Code Amount Analysis Report, Monitoring Learning Situation, Programming Learning Assistance 目 录 1.绪论 1 1.1研究背景及意义 1 1.2核心成果 1 1.3论文结构 2 2.需求分析 3 2.1业务需求分析 3 2.2用户及功能需求分析 4 2.2.1通用模块 4 2.2.2学生模块 5 2.2.3教师模块 5 2.2.4后台管理模块 6 2.2.5系统总体用例 6 2.4非功能需求分析 6 2.4.1 性能需求 7 2.4.2 质量属性 7 2.4.3 接口与约束 8 3.系统设计与实现 9 3.1 系统主框架 9 3.2 软件总体概述 10 3.3 数据库设计 13 3.3.1用户角色表 14 3.3.2用户抽象类表 14 3.3.3教师表 15 3.3.4学生表 15 3.3.5批量用户生成文件表 15 3.3.6课程表 15 3.3.7文本编辑抽象类表 16 3.3.8作业表 16 3.3.9作答表 17 3.3.10评论表 17 3.3.11组队表 17 3.3.12代码表 18 3.3.13邮箱验证 18 3.3.14 总体数据ER关系图 19 3.4 业务流程 20 3.4.1用户端主流程和基本业务 20 3.4.2特定用户业务流程 24 3.5项目目录结构 33 3.6系统界面设计 36 3.6.1用户端界面 36 3.6.2后台管理端界面 39 3.7具体实现 40 3.7.1代码量分析 40 3.7.2代码量可视化 44 3.7.3后台系统 49 3.7.4 作业提交管理 50 4.系统部署 56 4.1 阿里云部署 56 4.2 生产环境 57 5.结论 59 5.1 总结课题及成果 59 5.2 未来展望 59 参考文献 60 附 录:积码系统依赖的工具包 61 致 谢 62 1.绪论 1.1研究背景及意义 在信息时代,计算机编程是教育和学习的热点,对计算机专业人才的培养在效率和质量方面要有所提高[1]。根据2018年我国教育部发布的计算机类专业教学质量国家标准,计算机专业大学生在四年内总的实践代码量要超过两万行。

我作为软件工程本科专业的学生,经过四年学习计算机类相关知识,在学习过程中与学生和老师进行了沟通和讨论后,发现授课老师很难全面地掌握同学们的学习情况,学生自己也不是很准确地评判自身的编程水平。

针对编程水平判断进一步研究发现,要判断个人编程的水平能力,除了考查对知识体系的掌握情况,还必须依据个人实际编写的代码,包括编写速度、程序质量以及代码总量。其中速度和质量的判定需要特定的环境和条件来限定,同样一段代码程序解决的问题可能不同,需要达到的目标也会随具体问题而改变。而代码总量是最直观和具体的一个维度,也经常被用作编程能力的评判标准,根据2018年我国教育部发布的计算机类专业教学质量国家标准,计算机专业大学生在四年内总的实践代码量要超过两万行。

但出现掌握学习情况这个现象的一个很大原因就是学生们编写的代码零散地分布于课程作业、在线判题系统平台和个人实践项目当中。学生和老师们不便于记录代码以及统计和分析代码总量。

为了解决这个问题,本课题构思和设计了一种系统,它能够记录、统计和动态分析学生们的代码,并且与课程作业管理、在线判题系统的索引、学习交流和资源共享等功能相结合,作为一个在线平台来辅助计算机编程的学习。通过这个系统平台,学生可以将自己编写的代码随时随地上传,来记录和分析自己的编程学习历程,授课老师则可以随时随地分发作业和资源,查看和统计学生们的代码量,以了解其编程学习的进展情况。

计算机编程的学习,离不开积累代码量,就像一座大厦不能没有砖块的堆砌。由此,我将此系统取名为积码。

1.2核心成果 经过需求分析、系统框架分析、系统设计、编码实现、云端部署和验收测试,系统最终被构建和完善。积码系统的基本组件包括MySQL数据库,由Python编程语言开发的Django重量级web框架,搭配Bootstrap和jQuery前端框架。部署于阿里云轻量应用服务器,使用Nginx,uWSGI等web服务器进行搭建生产环境。用户能够通过互联网设备,如电脑、平板或手机客户端对系统网站进行访问。

系统包括五大核心功能:积码系统包括六大核心功能:用户信息管理(如注册,登录和查看个人信息等)、代码统计报告、自主练习、课程管理和作业管理,以及一个后台管理系统(涵盖用户管理,权限管理,课程管理,作业管理等)。

用户分为学生和老师两种身份。老师可以管理课程和作业,上传资源文件和查看学生的代码量统计报告。学生可以提交课程作业,下载课程资源,在个人自主练习区提交每日练习或每月项目,查看自己的代码量统计报告。

管理员可以自由设置权限、管理用户、课程和作业等。

1.3论文结构 本文以构建积码系统为主线,从设计到开发顺序地讲解系统的实现,包含了大部分重要的开发过程,下面我将简要地对全文章节的内容结构进行说明。

第一章,绪论。首先主要介绍课题项目的研究背景和意义,提出要完成的目标和要求。然后展示核心研究成果,介绍系统的主要构成,包括底部框架、数据库、部署平台、核心功能以及用户对象等。最后阐述说明论文的结构。

第二章,需求分析。对于任何一个系统开发都从需求分析开始,本章内容包括业务需求分析、用户需求分析、功能需求分析和非功能需求分析,全面展现系统要完成的目标和要求。

第三章,系统的设计与实现。这一章属于核心内容,包括系统主体框架,总体架构、数据库设计、业务流程、系统界面以及具体的代码实现。详细全面地讲解积码系统的构建和结构。此外说明一下,本文主要涉及积码系统的整体设计与实现,对测试部分不做述说。

第四章,系统部署。本章主要讲述在阿里云平台的系统部署,以及使用Nginx搭配uWSGI的软件负载均衡方案。

第五章,结论和未来应用。讨论积码系统扩展功能的更多可能性,以及与人工智能API和结合应用。

附录,是积码系统的依赖第三方包。

2.需求分析 需求分析是系统开发的第一步,也是最重要的步骤之一。通过需求分析,可以确定系统需要完成的功能,达到的性能,以及测试和验收的标准。在开发过程中,可能由于技术、市场或成本等问题,使需求发生更改。那么一定要有文档作为记录,保证系统开发的有序性和准确性。本章节将从积码系统的业务需求、用户需求和功能需求等三个角度进行分析[2],制定系统开发的目标,给客户和开发人员描绘出整个系统的轮廓。

2.1业务需求分析 业务需求的提出对象是客户和项目负责人等部门领导,通过沟通和积极提问,引导他们提出需求,但不能直接使用技术话语询问具体的技术要求。这是因为客户和领导这类群体未必是专业的技术开发者,但在他们脑海里一定有大概的系统蓝图,需求分析人员要做的是引导他们帮助自己将蓝图绘制出来。

经过与计算机专业的老师和学生们进行讨论分析后,得出了以下三点业务的需求。

1.背景 由于教育部提出的计算机类专业教学质量国家标准,要求计算机专业大学生在四年内总的实践代码量超过两万行。因此某高校的软件工程以及其他计算机相关专业的授课老师提出,要监控专业学生本科四年的代码总量,其中包括分布在课程作业、在线判题系统和个人项目的全部代码。辅助老师和学生监控学生的编程学习情况。

2.系统目标 搭建一个基于B/S的在线编程学习辅助网站,以供全院3000名学生和老师进行使用,顺畅运行并统计出每个学生四年的总代码量就可认为项目成功。

3.市场需求 当前学校没有一个平台或系统能够收集学生在练习过程中所产生的代码,使得老师和学生难以宏观地掌握学生的学习情况,不能满足监控计算机专业学生四年代码总量超过两万行的需求,需要一个专门的平台系统实现计算机专业老师和学生的需求。

2.2用户及功能需求分析 在业务需求分析后,我们可以分析出系统的用户需求,用户需求是指项目服务的主体人群的使用需求,围绕用户进行调查和挖掘,得出系统的主要功能模块,为系统设计、开发、完善和维护提供重要依据。

积码系统主要为三种用户进行服务:学生、老师和管理员。他们拥有不同的业务和权限,据此将系统分为了用户端和后台管理端,两个客户端拥有不同的访问入口。然后经过与计算机专业的学生和老师讨论后,得出积码系统应具有六大核心功能:用户信息管理(如注册,登录和查看个人信息等)、代码统计报告、自主练习、课程管理,作业管理,以及后台管理系统(包括用户管理,权限管理,课程管理,作业管理等)。

根据业务和用户的需求,可以进一步具体分析功能需求。功能需求是开发者在系统开发过程中实际硬性要求实现的功能模块,用户通过使用这些功能来和操作系统完成指定的事务。下面将阐述积码系统主要的功能模块:通用模块、学生模块、教师模块和后台管理模块,具体的代码实现将在第三章继续讲解。

2.2.1通用模块 此模块包括登录、找回密码、个人信息管理等子模块,详见表2-1通用模块表。

表2-1通用模块 模块 功能 描述 登录 登录 登录账号 退出 退出账号 注册 注册账号 找回密码 验证邮箱 验证填写的用户邮箱 发送验证码并验证 系统向用户邮箱发送验证码并验证用户所填写的验证码 验证新密码 用户填写新密码,系统验证是否符合标准 个人信息管理 个人信息 展示账号的个人信息 修改邮箱 修改账号邮箱 修改密码 修改账号密码 修改个人描述 修改个人信息中的个人描述 2.2.2学生模块 此模块包括代码量统计、加入课程、作业提交等子模块,详见表2-2学生模块表。

表2-2学生模块 模块 功能 描述 代码量统计 总量统计 按时间统计代码总增长量 编程语言统计 统计代码的编程语言种类 课程代码统计 统计不同课程的代码提交量 查看自我报告 查看自己代码量统计报告 加入课程 选择 选择公开课程 加入 加入公开课程 查看 查看自己课程内容详情 作业提交 查看 查看自己作业列表及详情 选择 选择自己的作业 填写 填写文本内容和上传文件压缩包 提交 点击提交 2.2.3教师模块 此模块包括课程管理、作业管理、查看学生情况等子模块,详见表2-3教师模块表。

表2-3教师模块 模块 功能 描述 课程管理 查看 查看自己课程列表及详情 创建 创建课程 修改 修改自己课程内容 删除 删除自己课程 作业管理 查看 查看自己课程作业列表及详情 创建 创建自己课程作业 修改 修改自己课程作业内容 删除 删除自己课程作业 查看学生情况 查看列表 查看自己课程学生列表及简要信息 查看报告 查看自己课程学生的代码量统计报告 2.2.4后台管理模块 此模块包括用户管理、权限管理、项目管理等子模块,详见表2-4后台管理表。

表2-4后台管理模块 模块 功能 描述 用户管理 查看 查看用户列表及详情 创建 创建用户 修改 修改用户个人信息内容 删除 删除用户 权限管理 查看 查看用户权限 创建 创建用户权限 修改 修改用户权限 删除 删除用户权限 项目管理 课程管理 对课程的增删查改 作业管理 对作业的增删查改 教师管理 对教师角色的增删查改 学生管理 对学生角色的增删查改 2.2.5系统总体用例 根据上述模块,可以用连线的方式将学生、教师和管理员对应的用户需求模块进行相连,绘制出积码系统的总体用例图,详情如图2-1所示。

图 2-1 积码系统总体用例图 2.4非功能需求分析 系统除了要满足客户指定的业务需求外,还要达到一定的性能、易维护、可靠性等非功能性需求。下面具体说明项目的性能需求、质量属性、接口和约束等四个方面的非功能需求。

2.4.1 性能需求 1.数据精确度 积码系统主要包括的数据有代码量、作业评分、日期等三个主要的数据,他们的精确要求详见表2-7。

表2-7数据精确度 数据类型 数据类型 精度 代码量 整数型 0~10000000000 作业评分 整数型 0~100 日期 YY-MM-DD 2. 时间特性 积码系统对应的数据处理及响应时间要求,详见表2-8。

表2-8时间特性 数据类型 时间特性要求 响应时间 小于2500毫秒 更新处理时间 小于4000毫秒 数据转换与传输时间 小于2000毫秒 运行时间 全年7*24小时在线 3. 兼用可适应性 这一特性共要求五点,一、系统人性化交互,操作简单;
二、运行环境,包括依赖的硬件和软件,其规格应中等偏下,让系统能够有较高的适应能力;
三、系统内部代码要求按标准进行注释,使后期易于进行维护和扩展;
五、兼容先各大主流浏览器包括谷歌、火狐、Safari、IE以及Opera,具体的版本号限制见下一小节的接口与约束。

2.4.2 质量属性 质量属性包括安全、正确、可移植、健壮、可靠和易用等6个维度,详见表2-9。

表2-9质量属性 属性名 具体要求 安全性 防止跨站请求伪造,用户密码加密。

正确性 系统站点正常显示,不会出现报错、页面缺失、乱码、数据错误等问题 可移植性 系统兼容现各大主流服务器平台以及操作系统 健壮性 系统同时支持3000人的并发操作,不导致崩溃。稳定运行1年以上 可靠性 系统出现异常报错和崩溃的概率小于5% 易用性 页面交互人性化、操作简单易懂,用户只需通过浏览器访问即可。

2.4.3 接口与约束 接口是指系统在运行环境中,需要依赖使用的主要硬件和软件以及要求兼容的浏览器版本,详见表2-10。

表2-10接口 接口类型 具体要求 硬件 1) CPU不低于1核;

2) 内存不小于1GB;

3) 支持1M以上宽带;

4) 40G以上SSD固态硬盘;

软件 1) 操作系统:Linux;

2) 数据库:MySQL5.7.20;

3) 运行环境:Python3+;

4) 开发语言:Python,JavaScript,HTML/HTML5,CSS/CSS3;

5) 使用框架:Django2.0,Bootstrap3+,jQuery2+ 6) 应用服务器:Nginx1.5+ 7) 网关:uWSGI2+ 浏览器 谷歌(版本10以上)、火狐(版本4以上)、Safari(版本5以上)、IE(版本9以上)以及Opera(版本11.1以上)
注:项目额外需要的第三方依赖见附录的积码系统完整依赖的工具包 3.系统设计与实现 本章将分为两个部分。第一部分讲述积码系统的设计,包含系统主框架、系统总体概述、数据库设计、业务流程、项目目录结构和系统界面等六个小节。第二部分为具体实现,重点讲解后端的代码量分析及可视化、后台系统、作业提交管理等三个部分模块的实现。

3.1 系统主框架 积码系统采用基于由Python语言编写的Django框架[3],其特点包括有完善的ORM关系映射、强大的路由映射、完善的视图模板的实现、健全的后台管理系统、强大的缓存支持、防止跨站请求伪造(CSRF)工具。由于这些特点,网站的搭建能够快速的实现。

Django采用MTV模式,与MVC不同,它由模型、模板和视图三部分组成。模型被称为Model,是数据存取层,处理与数据相关的所有事件,包括如何存取、如何验证有效。模板被称为Template,是表现层,负责如何把页面展示给用户。视图被称为View,是数据存取层,用于存取模型及调取恰当模板的相关逻辑,处于模型与模板的之间。除了以上基本三层,还有有一个表单文件,称为Form,负责验证一切用户输入的数据是否符合规定格式,以及保留用户上次输入的数据。

使用Django构建项目,需要通过配置文件(settings.py)和主路由(urls.py)来连接各个功能模块(app),十分注重高内聚低耦合。下面讲述各个部件的作用。

settings.py作为配置文件,用于设定功能模块路径、数据库连接、静态文件地址、用户媒体文件地址、中间件、session存储、系统语言和时间等,可以看做是连接外部和内部的庭院。

urls.py主路由文件是一个分发器,指向页面或者功能模块,方便集中管理。

功能模块也叫APP是由一个migrations文件夹和八个文件,分别是init、admin、apps、forms、models、tests、urls、views组成。八个文件分别对应的是初始化、管理员、应用名、表单、模型、测试、子路由、视图,而migrations文件夹是用来存放自动生成数据库更新的命令文件。

整个Django项目可以通过一个manage.py文件来统一调度:运行项目、创建超级用户、生成数据库、创建应用等。

除了主要的文件以外,还有一个wsgi.py文件,其中WSGI是web服务器网关接口(Web Server Gateway Interface)的缩写,它是python所选择的服务器和应用标准,一般用于开发模式的临时web服务器。

图3.1 Django-MTV模式示意图,可以直观地说明Django各应用如何相互作用。

图 3-1 Django-MTV模式示意图 3.2 软件总体概述 积码系统主要功能包括:代码量分析、课程管理、作业管理、作业提交、用户管理、后台管理。

代码量分析,包括作业代码量、课程代码量、总代码量,共分为三级,逐级累加。每次作业文件上交后,系统自动提取代码文件,识别编程语言,统计代码行数(除去空行)后,将代码量、时间、课程名、编程语言一并存入数据库。与学生用户的旧数据一起形成代码量报告,将数据可视化,包括总代码量-时间折线图、编程语言占比饼状图、课程占比柱状图。

课程管理,可以增加、删除、查找、更改课程。每个课程属于一个老师,多个学生,可以选择公开或不公开(公开则所有学生都可加入,不公开则选定学生才能加入)。

作业管理,可以增加、删除、查找、更改作业。每个作业属于一个课程;
每个作业都可以进行用户评论;
老师可以对学生提交的作业进行评价和打分,并下载课程学生作业成绩表 作业提交,学生选择一个作业,进行文字编辑和上传文件;
一个提交的作业属于一个学生,一个学生可以提交多个作业;
课程团队一人提交,则认定全员提交 用户管理,可以增加、删除、查找、更改用户。总共3个用户角色:学生、老师、管理员。用户基础属性:用户名、密码、邮箱、性别、创建时间、最后更改时间、个人描述;
老师额外属性:职称,可以进行课程管理,作业管理,查看学生代码量报告,更改密码、邮箱和个人描述;
学生额外属性:班级,可以加入课程,提交作业,查看代码量报告,更改密码、邮箱和个人描述;
管理员分为超级管理员、一般管理员,可以进行课程管理、作业管理、用户管理,此外超级管理员还可以更改用户权限。

由上述功能,我们可以绘制出系统总体架构,如图3-2所示,共分为六级,和用户模块、管理员模块两大类。

图 3-2 积码系统总体架图 3.3 数据库设计 数据库是作为系统数据存储的一个数据仓库,可以方便系统调用、添加、修改、删除数据。往往数据库的输入和输出是影响系统性能的关键因素之一,好的数据库设计结构可以减少不必要的冗余,提高系统性能。

常见的数据库类型有关系型、非关系型和键值数据库,这里采用的是社区版的关系型MySQL数据库。简单介绍一下,MySQL现属于Oracle旗下产品,分为社区版和商业版,具有开放源码的特点,较灵活,使用成本低,所以非常主流。

数据库是作为系统数据存储的一个数据仓库,可以方便系统调用、添加、修改、删除数据。往往数据库的输入和输出是影响系统性能的关键因素之一,好的数据库设计结构可以减少不必要的冗余,提高系统性能。

常见的数据库类型有关系型、非关系型和键值数据库,这里采用的是社区版的关系型MySQL数据库。简单介绍一下,MySQL现属于Oracle旗下产品,分为社区版和商业版,具有开放源码的特点,较灵活,使用成本低,所以非常主流。

数据库最重要的组成是表,就像一个一个的表,所有的数据都被存放在这样的结构当中。表是由列和行组成的,每一列有一个列名,它代表一类数据,每类数据都要求设置数据类型,包括字符、整数、浮点数或文本等。每一行则是一个记录,构成记录的某一个数据被称为字段。字段可以设置为允许空值或必填。主建,是一个表的唯一标识,通过它可以找到所在的表。外键则是关系其他表的不唯一标识。

下面介绍积码系统所需要用到的数据表单,包括数据名、列名和数据类型。为了便于读者更好地理解,这里对下列会用到的数据库字段的类型先做出详细的说明,详见表3-1。

表3-1 Django数据库字段类型 数据类型 表示含义 AutoField 指一个能够根据可用ID自增的IntegerField,系统默认主键 BooleanField 一个真/假(true/false)字段 CharField 一个字符串字段,适用于中小长度的字符串 DateField 日期字段 DateTimeField 时间日期字段,额外选项同DateField FileField 文件上传字段 FloatField 浮点数 ImageField 同FileField要验证上传的对象是一个有效的图片 IntegerField 整数 SmallIntegerField 和 IntegerField 类似,但是只允许在一个数据库相关的范围内的数值(通常是-32,768到+32,767)
TextField 不限长度的文字长度 TimeField 时分秒的时间显示 ForeignKey 外键,关联其它模型,创建关联索引 ManyToManyField 多对多,关联其它模型,创建关联表 OneToOneField 一对一,字段关联表属性 RichTextUploadingField 富文本,需要安装第三方依赖包 PositiveIntegerField 正整数 SlugField 嵌条 就是一段内容的简短标签,这段内容只能包含字母、数字、下划线或连字符 EmailField 一个能检查值是否是有效的电子邮件地址的 CharField 3.3.1用户角色表 表3-1是角色表,包含角色类型和用户id两类数据。角色包括学生和老师两个选项,用户id作为外键,关联对应的用户信息。

表 31角色表 序号 数据名 列名 数据类型 1 角色 Role SmallIntegerField 2 用户 User ForeignKey 3.3.2用户抽象类表 表3-2是用户抽象类表,包含姓名、性别、创建时间、最后更改时间、个人描述等五类数据,用于记录用户的基本信息,作为抽象类不单独储存在数据库当中。其实Django框架自带有用户表,包括了账号、密码、邮箱等基础信息。但往往这些信息不能满足业务实际需要,所以需要增加自定义用户表,可以定制业务角色所需的信息。这里就增加了姓名、性别、创建时间和个人描述等特殊信息。

表 32用户抽象类表 序号 数据名 列名 数据类型 1 姓名 Name CharField 2 性别 Gender SmallIntegerField 3 创建时间 Created DateTimeField 4 最后更改时间 Modified DateTimeField 5 个人描述 Description TextField 3.3.3教师表 表3-3是教师表,在引用用户抽象类表的基础信息外,增添职称信息。

表 33教师表 序号 数据名 命名 类型 1 用户 User ForeignKey 2 职称 Rank CharField 3.3.4学生表 表3-4是学生表,在引用用户抽象类表的基础信息外,增添班级信息。

表 34学生表 序号 数据名 命名 类型 1 用户 User ForeignKey 2 班级 Classes CharField 3.3.5批量用户生成文件表 表3-5是批量用户生成文件表,包括文件路径、文件名、创建状态等三类数据。此表用于存储批量创建用户的文件,如果文件上传后被使用,创建状态就会改被已被创建。

表 35批量用户生成文件表 序号 数据名 命名 类型 1 文件路径 File FileField 2 文件名称 Name CharField 3 创建状态 Is_create CharField 3.3.6课程表 表3-6是课程表,包括课程名称、班级、课程描述、公开状态、老师和学生等六类数据。课程表的特点是:每个课程属于一个老师,一个老师拥有多个课程,所以老师作为外键。一个课程包含多个学生,一个学生有多个课程,所以数据类型设置类多对多。

表 36课程表 序号 数据名 命名 类型 1 课程名称 Cname CharField 2 班级 Classes CharField 3 课程描述 Description TextField 4 公开状态 Opened SmallIntegerField 5 老师 Teacher ForeignKey 6 学生 Student ManyToManyField 3.3.7文本编辑抽象类表 表3-7是文本编辑抽象类表,包括正文,创建时间,修改时间和文件路径等四类数据。这个表的信息需要被作业表、作答表所引用,因此作为抽象类,不单独储存在数据库当中。

表 37文本编辑抽象类表 序号 数据名 命名 类型 1 正文 Body RichTextUploadingField 2 创建时间 Created DateTimeField 3 修改时间 Modified DateTimeField 4 文件路径 File FileField 3.3.8作业表 表3-8是作业表,包括标题,摘要,发布时间,作业状态,组队状态,浏览量和课程id等七类数据。作业表的特点是,每个课程有多个作业,一个作业属于一个课程,所以课程作为外键。

表 38作业表 序号 数据名 命名 类型 1 标题 Title CharField 2 摘要 Slug SlugField 3 发布时间 Published DateTimeField 4 作业状态 Status CharField 5 组队状态 Group SmallIntegerField 6 浏览量 Views PositiveIntegerField 7 课程 Course ForeignKey 3.3.9作答表 表3-9是作答表,包括作者,课程,作业和分数等四类数据。作答表的特点是,一个作业有可以多次作答,一次作答属于一个作业,对应的作者和课程也是如此。分数是由老师评定。

表 39作答表 序号 数据名 命名 类型 1 作者 Author ForeignKey 2 课程 Course ForeignKey 3 作业 Homework ForeignKey 4 分数 Score IntegerField 3.3.10评论表 表3-10是评论表,包括用户名称,评论内容,作业id和评论时间等四类数据。评论表的特点是每份作业可以有多人评论,每条评论属于一个作业,因此作业设为外键。

表 310评论表 序号 数据 命名 类型 1 用户名称 Username CharField 2 评论内容 Text TextField 3 作业 Homework ForeignKey 4 评论时间 Created DateTimeField 3.3.11组队表 表3-11是分组表,包括领队,课程,成员和编辑状态等四类数据。老师可以给课内的学生分组,老师相当于领队,成员是多个,可以设置为不可编辑和可编辑两种状态。

表 311组队表 序号 数据 命名 类型 1 领队 Leader ForeignKey 2 课程 Course ForeignKey 3 成员 Member ManyToManyField 4 编辑状态 Edit SmallIntegerField 3.3.12代码表 表3-12是代码表,包括学生、课程、作业、创建时间、最后更改时间。代码量、编程语言等七类数据。和作答表逻辑类似,每份作业有一个代码表。但积码系统最常用到的功能就是代码量统计报告,对数据库的调用也最频繁,所将代码信息单独成表,用空间换时间提高检索速度。

表 312代码表 序号 数据 命名 类型 1 学生 Student ForeignKey 2 课程 Course ForeignKey 3 作业 Homework ForeignKey 4 创建时间 Created DateTimeField 5 最后更改时间 Modified DateTimeField 6 代码量 Code IntegerField 7 编程语言 Language CharField 3.3.13邮箱验证 表3-13是邮箱验证,包括验证码、邮箱、发送时间和是否有效等五类数据。其实Django自带有邮件发送的函数功能,但这里想更加自定义,所以创建了对应的邮箱验证表。验证码用于存储发送给目标邮箱的随机验证码,邮箱是目标邮箱,发送时间用于记录有效时间,用户名及用户的姓名。如果发送的验证码过了有效时间,有效状态则修改为False。

表 313邮箱验证表 序号 数据 命名 类型 1 验证码 Code CharField 2 邮箱 Email EmailField 3 发送时间 Send_time DateTimeField 4 用户名称 Username CharField 5 有效状态 Active BooleanField 3.3.14 总体数据ER关系图 根据以上13个小节所述的数据表结构及其关系,我们可以绘制出积码系统的总体数据ER关系图[4],详见图3-3 图 3-3 积码系统总体数据ER图 3.4 业务流程 用户端的流程与后台管理员端流程相比,显得更为重要,因此本节主要讨论用户端流程,包括用户端主流程、用户基本业务流程和特定角色业务流程。通过对这些流程的阐述,进一步让读者对整个系统有基本的认识。

3.4.1用户端主流程和基本业务 用户端主要流程按角色可分为两条支线,可参照图3-4用户端主流程图,从用户登录开始,到用户进入主页,系统根据用户身份可分为学生业务和老师业务。两个业务有共同点,我称其为用户基本业务,包括用户登录和登出、查看个人信息、修改自我描述、修改密码、修改邮箱等五大业务。

图 3-4 用户端主流程图 图3-5描述了查看个人信息业务,从用户选择本业务开始、页面显示个人信息,包括用户名、邮箱、自我描述、性别、用户角色,若用户为学生则还有班级和总代码量,若用户为老师则还有职称。进入本业务后还可以选择修改个人信息。

图 3-5 查看个人信息业务流程图 图3-6为修改密码流程图,选择业务后,先输入原密码并判断是否正确,若正确则进入下一步填写新密码,但错误则选择重新输入或退出。填写新密码需要符合三个标准:1.至少6个字符;
2.小于20个字符;
3.确认密码与新密码一致,若有任意一项不符合规定,则修改失败出现错误提示后,选择继续修改或结束业务。当输入的新密码符合了三项规定后,系统更新密码,结束业务。

图 3-6 修改密码流程图 图3-7是修改邮箱业务,此项业务还涉及了外部第三方程序,不过我们重点讲解系统内部业务。首先同修改密码一样,我们需要输入用户原密码,以保证为用户本人进行操作。当密码验证通过后,可以输入要更换的新邮箱,这时系统会先验证输入的邮箱格式是否正确,如XXX@XXX.XXX。之后用户点击发送按钮,系统将随机生成验证码并发送至新邮箱,用户在外部通过登录新邮箱打开验证码邮件后获得验证码,再至页面输入验证码,然后系统判断验证码是否有效,若有效则系统更新用户邮箱信息后结束业务,否则提示错误,用户可以选择重新填写、重新发送验证码、重新填写新邮箱地址或者结束业务。

图 3-7 修改密码流程图 图3-8为修改自我描述流程图,进入修改页面后,有一个文本输入框,用于填写自我描述,默认显示为原内容,修改后字数不能超过200个,否则修改失败,显示错误提示,用户可以选择继续修改或结束业务。修改成功后,数据库更新数据,然后自动跳转到个人信息页面,结束业务。

图 3-8 修改自我描述流程图 3.4.2特定用户业务流程 所有用户角色都拥有基本业务。学生用户还可以进行加入课程、上交作业和查看代码量报告等业务。老师用户则可以创建课程、发布作业、上传视频等业务。下面将选取部分业务进行讲解,读者可以类比剩余业务流程。

图3-9是加入课程业务,学生可以加入公开的课程。

图3-10是上交作业业务,这里学生需要填写正文和上传作业文件,若没有文本空缺或文件空缺,系统则自动分析文件里所有代码文件的代码量。

图3-11是查看代码量报告业务,学生用户可以查看自己的代码量报告。两者流程较为简单。

图3-12是创建课程业务,老师填写对应的课程信息,然后发布。

图 3-12 创建课程流程图 3.5项目目录结构 构建项目的过程中,设计目录结构是十分重要的。Django框架主要包含主应用文件夹(项目名)、子应用文件夹(apps)、静态文件夹(static)、媒体文件夹(media)、模板(templates)、管理文件(manage.py)和外加一个第三方插件管理文件夹或文本(requirements)
积码系统的在项目中的英文命名为:jicode,所以项目的主目录如图3-13所示,共分为8个文件。

图 3-13 项目主目录图 首先是子应用文件夹(apps),内部包含项目的所有功能模块:代码量分析(codeAnalysis),评论(comment),课程(course),邮箱验证(emailVerify),学生分组(group),提交作业(handin),作业(homeworkapp),后台管理员(myadmin),用户基本(userBase),视频(video),详见图3-10。

这些应用功能的划分遵循一个重要原则:单一化,使得功能之间复用性提高,达到高内聚低耦合的效果。

图3-14中红框内部分就是每个应用功能的组成文件,包括:python文件初始化(init),管理员控制(admin),应用命名(apps),表单验证(forms),数据模型(models),测试(tests),路由分发(urls),视图逻辑(views)。其中forms、models、urls、views四个部件尤为重要,一般开发过程是由model开始创建数据模型,然后views编写功能函数,forms用于输入数据验证,最后在urls里创建对应views功能函数的路由地址,读者可以回顾图3-1 Django的MTV模式。

图 3-14 项目apps目录图 接下来是主app目录,这里是项目功能的一个集中点,通常在项目创建之初就被建立,可以说是首要设置的文件夹,通常被命名为项目的名字。其中settings.py是首要被编写的文件。在settings.py中你可以设置项目apps路径,数据库连接,系统语言和时间,媒体路径,静态文件路径,第三方插件的属性等重要内容。因为这一文件比较重要,且容易出错,所以我在下一节会将积码系统的setting内容与读者们分享,它目录结构可以见图3-15。

图 3-15 项目主app目录图 再往下是媒体和静态文件,媒体文件夹通常就是负责集中用户上传的文件,静态文件夹(static)则是模板页面会用到的脚本语言(js)、样式表(css)、图片(img)、字体(fonts)和第三方插件所用到的静态文件,如图3-16所所示。

图 3-16 项目主static目录图 下面一个较为重要的文件就是模板文件(templates),这里负责的是系统前端页面,按apps内应用功能划分,不同的功能会调用不同的页面,这些页面都为html文件。在html页面内通过应用功能的urls地址来调用所需要的函数,以及通过 {% load static %} 行命令来载入静态文件。现在有很多开源的前端框架[5],比如Vue、React、Bootstrap[6]和Angular等等,可以令项目开发快速进行,积码系统采用的是基于Bootstrap和jQuery制作的hAdmin前端框架。图3-17就是templates的目录图。

最后是还有三个文件虚拟环境(venv)、Django管理文件(manage)和第三方依赖插件(requirements)。Venv是Django的python虚拟环境,构建项目时产生的。Manage也是最初自动生成的文件之一,用于管理Django项目的基本功能,如:创建项目、创建应用app、开启服务器、更新数据库等等基础操作。Requirements则是用于记录项目所需要用到的全部第三方依赖插件,便于项目迁移时重新安装环境。

图 3-17 项目主templates目录图 一个好的系统项目目录,可以让开发人员们明确分工,减少冲突,从而调高开发效率。此外系统界面设计是另一个蓝图,当我们进行开发之前一定要有整个系统的界面或草图。好比建造一个大厦,没有施工图那么工人是无法开工的。所以下一章我们将继续讲解积码系统的界面设计。

3.6系统界面设计 本节将讲述系统八个重要模块的界面设计,其中涉及到用户端登录、课程详情、提交作业、学生情况、代码量统计报告、后台登录、后台主页和后台增加作业,以此来描绘整个系统的风格和给读者带来用户体验。在这说明一下,积码系统后续会有更新,所以下列展现的界面可能不是积码系统实际部署时的样貌,不过大致风格相同。

3.6.1用户端界面 用户进入系统前,首先要进行登录,如图3-18。风格按流行的扁平化设计,以白色线条作为背景打底,附加磁吸棒作为点缀。页面正中为登录窗口,包含登录,用户名,密码,忘记密码等字样,颜色为蓝色。系统名字 ‘JiCode’在登录框顶部居中,颜色为蓝色。通体以蓝白为主色调,显得比较简约自然。

图 3-18 用户端登录界面 用户进入系统后,页面主要由三部分组成,一个是左侧导航栏,另一个为顶部信息栏,以及右端主体。其中左侧导航栏和顶部信息栏在系统中恒定不变,当切换页面时,只有右端主体发生变化。

在课程详细页面中,分为两部分:导航和主体。课程导航根据用户身份不同,分为教师导航和学生导航。其中教师导航为:已发布作业、待发布作业、添加作业、分组情况、创建分组、所有学生、已发布视频、待发布视频和添加视频;
学生导航只有:所有作业、以提交作业和全部视频。

图 3-19 老师课程详情界面 老师进入课程详细页面,默认选择已发布作业,而学生默认选择所有作业。这时,右端主体会以列表式显示所有已发布的作业详情,并可以对某个作业进行操作,如图3-19。

学生进入提交作业页面,有正文填写本文框,选择文件和提交按钮。

图 3-20 学生提交作业界面 积码系统最重要的特点就是代码量统计报告,是系统根据用户提交的代码文件而产生的数据,进行统计分析,并通过基于echarts的pyecharts第三方插件形成可视化报告。报告内容包括总代码量增长图、惯用编程语言分布饼图和课程代码量分布直方图。这三个不同方面可以为学生提供很好地参考价值,判断自己编程学习的广度和宽度,详见图3-21。

图 3-21 学生代码量统计报告界面 3.6.2后台管理端界面 积码系统的后台端是Django框架自带的后台管理,并通过第三方插件simpleui优化了界面。simpleui是一个tompeppa基于element-ui+vue开发的django admin 主题插件。其重写和优化90%以上的页面,让django admin更符合国人的使用习惯,不需要修改原admin任何代码,100%兼容原生admin。登录界面如图3-22所示。

图 3-22 后台管理端登录界面 如图3-23所示,在后台主页,侧栏显示可以管理的应用功能(app),以及基本用户认证和授权,而主体首页显示快捷操作和最近动作。顶栏包括用户信息,用户端跳转,主题更换,字体更换,全屏显示等。

图 3-23 后台管理端主页界面 以创建学生信息为例,选择学生表一栏,主体就会出现搜索栏,增加和删除按钮。然后所有学生信息以列表式显示,点击名字可以进行修改,十分方便,见图3-24。

图 3-24 后台管理端创建学生信息界面 前端界面如上所示,那么后台是如何为前端提供数据和计算?计算逻辑又是如何?在下一章节我们将继续讨论积码系统核心代码的设计思路和实现。

3.7具体实现 本节对积码系统部分核心代码的设计思路和具体实现的讲解,共分为三个部分,一、代码量分析及可视化,二、后台系统,三、作业提交管理 3.7.1代码量分析 为了进行代码量的分析,我们需要先在数据库记录学生代码量数据,那么我们要考虑数据模型的形式。经过讨论分析,我们得出三种形式:一、将每次作业量代码累加,作为学生的一个属性,并入学生表中;
二、每个学生拥有属于自己的代码表,记录每一项新增代码量记录;
三、将所有代码量新增记录聚集为一张表,每条记录包括作业、课程和学生信息。

进而我们需要思考数据可视化呈现的结果,是要包含有新增代码量的数目、时间、所属课程和所属编程语言。因此形式一被排除,我们不能在学生属性中加入过多代码属性;
至于形式二,在学生数量大于2的情况下非常不可取,会造成数据库冗余和拥挤;
所以我们选择形式三,将所有代码量新增数据汇聚成一张表代码量表,虽然这样会增加查找时间,但查找的时间复杂度只是O(n)。

通过分析提交的代码作业,每份作业可能提交多种类型的编程语言文件,这里采用字符串来记录这类数据。下面是代码量分析的模型源码:
# codeAnalysis/models.py from django.db import models from apps.course.models import Course from apps.homeworkapp.models import Homework from apps.userBase.models import Student #按一份作业为一条数据插入 class FileCodes(models.Model): student = models.ForeignKey(Student, on_delete=models.CASCADE) course = models.ForeignKey(Course, on_delete=models.CASCADE) homework = models.ForeignKey(Homework, related_name=“filecodes“, on_delete=models.CASCADE) created = models.DateTimeField('创建时间', auto_now_add=True) modified = models.DateTimeField('最后更改时间', auto_now=True) code = models.IntegerField('文件总代码量', default=0) language = models.TextField('编程语言代码量', null=True) class Meta: verbose_name = “作业代码量“ verbose_name_plural = verbose_name #自定义编程语言代码文件后缀 file_ext = { 'py':'Python', 'java':'Java', 'c':'C', 'cpp':'C++', 'cc':'C++', 'cs':'C#', 'bas':'VisualBasic', 'js':'JavaScript', 'php':'PHP','html':'HTML', 'sql':'SQL数据库', 'mdb':'SQL数据库', 'dbf':'SQL数据库', 'mdf':'SQL数据库', 'swift':“Swift“, 'rb':'Ruby', 'm':'Objective-C', 'mm':'Objective-C++'} #关联文件格式对应的编程语言 def get_language(file_name): language = file_ext if file_name in language: return language[file_name] else: return 'other' 将常用编程语言单独做一个自定义字典,方便增加和修改。用一个实际作业文件举个例子,见图3-25。

图 3-25 举例文件目录 假设test.php文件代码量为100行,test.java文件代码量为100行,test.py文件代码量为100行,那么将会在FileCodes表中插入一条数据,其中language属性值为:py_100;java_100;c_0;cpp_0;cc_0;cs_0;bas_0;js_0;php_100;html_0;sql_0; mdb_0;dbf_0;mdf_0;swift_0;rb_0;m_0;mm_0;nofind_0; 再通过python字符串分割(split)既可以得到对应的编程语言代码量。

对于作业文件,要求上传的是经过ZIP压缩的文件,一是可以减少存储空间,二来统一格式。这里共分为三个函数:
1.codes_create函数,获取作业文件、学生号、作业号、课程号,然后判断是否为可更新的数据,再更新数据库。代码如下:
def codes_create(files, course_id, student_id, homework_id): pl = {'code':0} #编程语言代码量累计字典 for ext in file_ext: pl[ext] = 0 filetocode(files, pl) #搜寻函数 # 若压缩包含代码文件增增加数据库记录 if pl['code']>0: language = '' for ext in file_ext: #以文本格式存储编程代码量 language += ext+'_'+str(pl[ext])+';' #新增数据 FileCodes.objects.create(course_id=course_id,student_id=student_id, homework_id=homework_id,code=pl['code'],language=language) 2. filetocode函数,解压zip包,然后搜寻代码文件,遇见压缩包继续解压,若为代码文件则通过计算函数获得代码量。代码如下:
def filetocode(files, language): f = ZipFile(files, 'r') for file in f.namelist(): ext = file.split('.')[-1].lower() if ext == 'zip': filetocode(f.open(name=file), language) #递归查找 elif ext in file_ext: # 以读方式打开文件,并依次读取每行 codeline = f.open(name=file).readlines() #调用代码行计算函数 language[ext] += countcode(codeline) #累加作业总代码量 language['code'] += language[ext] 3. countcode函数,按一定规则来计算代码行量,不同编程语言有不同的书写规则,这里就简单地判断非空行来计算,若有实际需求还可继续更改。代码如下:
def countcode(codeline): temp = 0 for line in codeline: # 去掉每行头尾空白 line = line.strip() if not len(line): continue temp += 1 return temp 3.7.2代码量可视化 有了代码量数据后,下一步就是将数据可视化[7]。Matplotlib是Python做可视化最传统的工具[8],优点是快速简洁,缺点是图形样式固定不可交互。经过对比效果,最终我选定了用pyecharts,这是一个用于生成 Echarts 图表的类库。而Echarts 是百度开源的一个数据可视化 JS 库,主要用于数据可视化。这个图表库样式精美可交互,非常适合用于展示数据。前面章节有提及代码量报告有三个部分:总代码量增长折线图、编程语言分布饼图和课程代码量分布直方图。下面将具体讲解这三个部分的代码实现。

1.总代码量增长折线图,效果见图3-26,这里我们要用到的数据是学生按天为单位的代码量,然后需要计算出增长量和累计量,并按时间顺序从早到晚。下面是具体代码实现:
user = get_object_or_404(User, pk=pk) #获得用户id student = user.role.student.id #获得用户的学生id codes = FileCodes.objects.filter(student=student) #获得学生的全部代码量数据 '''折线图''' # 设置折线图标题位置 data_total = [] data_increment = [] data_time = [] data_tem = {} # 数据预处理 for data in codes: if data.created.date() not in data_tem: data_tem[data.created.date()] = 0 data_tem[data.created.date()] += data.code #日期按从早到晚排序 data_tem = sorted(data_tem.items(),key=lambda x:x[0]) total = 0 # 数据封装 for i in data_tem: total += i[1] data_total.append(total) data_increment.append(i[1]) data_time.append(i[0]) line = Line(“总体“, '代码量(行)统计图', title_top='45%', title_pos='1%', title_text_size=20) # 总量线 line.add(“累计总量“, data_time, data_total, is_datazoom_show=True,datazoom_type='both',line_width = 2) # 增量线 line.add(“每日增量“, data_time, data_increment,is_label_show=False, legend_top='49%', legend_pos='18%',is_smooth=True, mark_point=[“max“],line_width = 2) 图 3-26 代码量可视化-折线图 2. 编程语言分布饼图,效果见图3-27,这里我们要用到的数据是学生按编程语言为单位的代码量,然后需要从FileCodes数据属性的language里分割出编程语言的代码分布情况,下面是代码实现:
'''饼图''' # 设置数据 data_language = [] data_language_code = [] data_tem = {} # 数据预处理 for data in codes: # 编程语言记录格式为:'编程语言文件后缀名' + '_' + ';' language = data.language.split(';') language.pop() for pl in language: ext = file_ext[pl.split('_')[0]] #将后缀转换为名称 code = int(pl.split('_')[1]) if ext not in data_tem: data_tem[ext] = 0 data_tem[ext] += code # 数据封装 for i in data_tem: if data_tem[i] != 0: data_language.append(i) data_language_code.append(data_tem[i]) # 设置主标题与副标题,标题设置居中,设置宽度为900 pie = Pie(“编程语言“, “代码量分布图“, title_top='1%', title_pos='49%', title_text_size=20) # 加入数据,设置坐标位置为【75,50】,上方的colums选项取消显示, 显示label标签 pie.add(“编程语言代码量“, data_language, data_language_code, center=['75%', '28%'], is_legend_show=True,is_label_show=True, radius=[0,'37%'],legend_orient=“vertical“,legend_pos='48%',legend_top='12%') 图 3-27 代码量可视化-饼图 3. 课程代码量分布直方图,效果见图3-28,这里我们要用到的数据是学生按课程为单位的代码量,简单地读取FileCodes数据的course和code属性即可,下面是代码实现:
'''柱状图''' data_course = [] data_course_code = [] data_tem = {} # 数据预处理 for data in codes: if data.course.cname not in data_tem: data_tem[data.course.cname] = 0 data_tem[data.course.cname]+=data.code # 数据封装 for i in data_tem: data_course.append(i) data_course_code.append(data_tem[i]) # 设置柱状图的主标题与副标题 bar = Bar(“课程“, “代码量(行)分布图“, title_top='45%', title_pos='50%', title_text_size=20) # 添加柱状图的数据及配置项 bar.add(“课程代码量“, data_course,data_course_code, is_legend_show=False,mark_line=[“average“], mark_point=[“max“, “min“], xaxis_rotate=20) 图 3-28 代码量可视化-直方图 4. 统一布局,按折线图左下,饼图右上,直方图右下,学生简要信息左上,并定位到code_analysis.html页面。

# 设置三个图表的相对位置 grid = Grid(page_title='代码量统计报告',width='100%',height='100%') grid.add(line, grid_height='35%', grid_width='40%', grid_bottom='10%', grid_right='54%') grid.add(bar, grid_height='35%', grid_width='40%', grid_bottom='10%', grid_right='5%') grid.add(pie) grid.add(info) template = loader.get_template('codeAnalysis/code_analysis.html') context = dict(myechart=grid.render_embed(), script_list=grid.get_js_dependencies(), 3.7.3后台系统 积码后台管理使用的是Django自带的admin模块[9],操作十分便捷,再加上simpleui的主题优化,使得整个后台管理界面优美,交互性良好。

首先是更换语言和时间,因为默认是英文,所以需要通过在settings.py里进行设置,代码如下:
LANGUAGE_CODE = 'zh-hans' TIME_ZONE = 'Asia/Shanghai 安装django-simpleui==3.9 第三方插件,再添加至settings.py的 INSTALLED_APPS一栏,代码如下:
# Application definition INSTALLED_APPS = [ 'simpleui', #插入在admin上面 'django.contrib.admin', 'django.contrib.auth', ………, ] 'apps.emailVerify', 'apps.group', 'apps.handin', 'apps.homeworkapp', 'apps.userBase', 'apps.video', 'apps.myadmin', 'ckeditor', 'ckeditor_uploader', ] 然后通过命令:python manage.py createsuperuser创建超级管理员账号后,启动服务器可以通过默认地址127.0.0.1:8000/admin进入后台管理端。这里为了增加后台安全,我在主应用url里更改了admin的地址为:path('738663luanma/myadmin/', admin.site.urls)。

下一步进行管理配置,积码系统后台主要管理的是用户、课程、作业和视频,这里我们以用户管理为例。用户管理又分为基础用户(无身份),老师用户,学生用户。

我单独将后台设置作为一个应用功能叫myadmin,便于修改,直接在admin.py文件内操作。下面老师信息管理的设置,代码如下:
class TeacherAdmin(admin.ModelAdmin): list_display = ('name', 'ranks', 'gender', 'created', 'modified',) list_per_page = 5 # 设置每页显示多少条记录,默认是100条 list_editable = () # 设置默认可编辑字段 date_hierarchy = 'created' # 详细创建分层筛选 ordering = ('-created',) # 设置默认排序字段,负号表示降序排序 inlines = [ CourseInline, # Inline把CourseInline关联进来 ] search_fields = ('name',) # 搜索字段 admin.site.register(Teacher, TeacherAdmin) # 注册到管理器 上面代码表明在后台端的显示老师表的管理,管理对老师的增删查改,然后在主体显示所有老师的信息包括姓名、职称、性别、创建时间和修改时间,每个主体页面显示5行记录,按创建时间排序,可编辑所有字段等等。

此外还可以将注册到管理器变为装饰器:@admin.register(Teacher)加在类名上面。

3.7.4 作业提交管理 作业提交管理分为创建提交、修改提交、删除提交、提交作业列表。

1.创建提交。当学生共有两种类型作业可以提交:个人或小组。当作业属于个人时,提交成功后会新增自己提交的记录;
当作业属于小组时,只要其中一个组员创建提交后,就会新增全部组员的提交记录。并在提交过程中调用代码量分析模块。代码如下:
@method_decorator(login_required, name='dispatch') class HandinCreate(CreateView): model = Handin form_class = HandinForm template_name = 'handin/handin_form.html' def form_valid(self, form): homework = Homework.objects.get(id=self.kwargs['pk']) course = Course.objects.get(id=self.kwargs['pkr']) file = form.cleaned_data['file'] student = self.request.user.role.student.id if homework.group == 0: form.instance.course = course form.instance.homework = homework form.instance.author = self.request.user.role.student # 更新课程代码量和总代码量 # 代码表增加 codes_create(file,course_id=course.id, student_id=student, homework_id=homework.id) return super().form_valid(form) else: # 小组作业,一人提交则全部提交 form.instance.course = course form.instance.homework = homework form.instance.author = self.request.user.role.student if Group.objects.filter(course=course, member=self.request.user.role.student): group = Group.objects.get(course=course, member= self.request.user.role.student).member.all() for each in group: if each != self.request.user.role.student: Handin.objects.get_or_create(course=course, homework=homework, author=each) # 代码表增加 codes_create(file, course_id=course.id, student_id=each, homework_id=homework.id) return super().form_valid(form) else: form.instance.course = course form.instance.homework = homework form.instance.author = self.request.user.role.student # 代码表增加 codes_create(file, course_id=course.id, student_id=student, homework_id=homework.id) return super().form_valid(form) 2.修改提交。当学生可以重新上传文件、和文本,这是系统会删除之前的旧记录。

@method_decorator(login_required, name='dispatch') class HandinUpdate(UpdateView): model = Handin form_class = HandinForm template_name = 'handin/handin_form.html' def form_valid(self, form): file = form.cleaned_data['file'] homework = self.kwargs['pkr'] course = self.kwargs['pka'] student = self.request.user.role.student.id # 代码表更新 FileCodes.objects.filter(course_id=course, student_id=student, homework_id=homework).delete() codes_create(file, course_id=course, student_id=student, homework_id=homework) return super().form_valid(form) 3.删除提交。直接在数据库中删除即可,提交作业列表里的作业状态修改为未提交。代码如下:
@method_decorator(login_required, name='dispatch') class HandinDelete(DeleteView): model = Handin def get_success_url(self): return reverse_lazy('homeworkapp:homework_list', args=[str(self.kwargs['pka'])]) def get_object(self, queryset=None): homework = id=self.kwargs['pkr'] course = self.kwargs['pka'] student = self.request.user.role.student.id #self.kwargs['pk']是id号,'pkr'是homework_id, 'pka'是course_id号 # 代码表删除 FileCodes.objects.filter(course_id=course, student_id=student, homework_id=homework).delete() obj = super().get_object(queryset=queryset) if obj.author != self.request.user.role.student: raise Http404() return obj def get(self, request, *args, **kwargs): return self.post(request, *args, **kwargs) 4. 提交作业列表。显示需要提交的作业,列表标题包括作业名,发布时间,查看详情,提交状态,评分。代码如下:
class HandinDetail(DetailView): model = Handin template_name = “handin/handin_detail.html“ def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) homework = Homework.objects.get(id=self.kwargs['pkr']) context.update({ 'homework': homework, }) return context @method_decorator(login_required, name='dispatch') class HandinList(ListView): paginate_by = 5 template_name = 'handin/handin_list.html' def get_queryset(self): return Homework.objects.get(id=self.kwargs['pk']).handin.all() @method_decorator(login_required, name='dispatch') class HandinListDone(ListView): template_name = 'handin/handin_list_done.html' paginate_by = 5 def get_queryset(self): return Handin.objects.filter(course__id=self.kwargs['pk']).filter( author=self.request.user.role.student).order_by('-id') def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) course = Course.objects.get(id=self.kwargs['pk']) if Group.objects.filter(course=course, member=self.request.user.role.student): group = Group.objects.get(course=course, member=self.request.user.role.student).member.all() else: group = '' context.update({ 'course': course, 'group': group, }) return context 总的来说,在Django框架下,实现模块功能的语句规则比较易懂,能够很快上手。通过讲解和展示部分核心代码,可以一览积码系统的整个代码风格和逻辑,希望给读者带来一定的参考价值。

4.系统部署 系统设计和实现后,一般不会直接在开发人员的电脑上供用户使用,而是需要部署到一个平台,保证不会有人为因素影响系统的运行。也方便测试人员模拟真实的用户体验。当然平台可以使本地自己组建的,也可以选择云平台服务提供商进行租赁。截止2020年,市面上已经有多家云平台服务提供商,国外包括亚马逊、谷歌等,国内则有阿里、百度、腾讯等数量非常多家。云平台服务提供商首先是为自己旗下产品提供设备平台,其次用闲置的资源做租赁服务。我们暂时不考虑系统数据会不会被云平台提供商给非法获取,就其安全性而言还是有一定保障的,特别是阿里云。阿里旗下的支付宝被广泛使用,其支付安全是必须保障的,因此其服务器的防御能力也不弱。我根据对积码系统项目的安全、类型和成本来考虑,最终选择了国内的阿里云平台进行租赁。所以这一章我将主要讨论阿里云平台的部署,以及系统性能的优化方案。

4.1 阿里云部署 首先我选择购买租赁了阿里云的轻量应用服务器,配置为:1核CPU,2G内存,40G硬存,预设基于Linux的Ubuntu操作系统(命令行界面)。购买成功后,会得到一个公网地址,以及私网地址。通过公网地址可以在本地访问到预设的Linux系统。

刚使用系统时,一般要修改系统Root用户密码,以及进入阿里云服务器的控制平台,修改对外开放的端口号范围。修改好基础配置后,要安装积码系统环境。

首先安装Python3.7语言环境,Pyenv版本管理,Virtualenv虚拟环境,和Screen管理会话软件。Python是积码项目的编写语言。Pyenv用于管理不同Python版本的工具。Virtualenv则是为项目系统搭建一个Python的虚拟环境,在这个环境里没有第三方依赖包,非常干净。Screen是用于保持项目24小时运行的管理窗口软件。

然后通过Pyenv和Virtualenv创建一个属于积码系统的Python3.7工作环境,我取名为jicode。

然后在本地的Linux,通过SCP命令传输整个项目文件到指定目录下。这里我使用的是MAC OS系统,属于Linux系统,若读者的系统是Windows,则可以使用其他工具,如WinSCP。

项目传输好了后,启动jicode虚拟环境,并用命令加载项目根目录下的Requirements.txt文件来安装项目所需要的第三方依赖包。

最后你就可以尝试用runserver命令启动项目,注意的是请执行python manage.py runserver 0.0.0.0:端口号,添加0.0.0.0是为了能够在任意局域网内访问站点,若不填,则默认在本地127.0.0.1上才能访问。端口号依据之前修改的端口范围填写,不过要注意端口占用问题。

4.2 生产环境 上一节将阿里云部署的流程大致理清,但项目要正式运行还不止于此。这里要理清三个概念:开发环境、测试环境和生产环境。web系统的开发过程一般是先开发,后测试,最终上线,每个过程有对应的环境和服务器平台。

开发环境,开发人员会使用专门用于开发的服务器,为了开发和调试方便,配置比较自由,会打开全部错误报告。

测试环境,使用的服务器和配置会和生产环境相同,模拟真实用户的体验,测试出系统在使用过程中可能发生的问题。

生产环境,这里会使用能够支持高并发的高性能服务器,关闭错误报告,启用错误日志。这个环境也被称作真实环境。

补充说明一下错误报告和服务器。错误报告是指在对系统进行操作的过程中,出现Bug即错误时,系统会自动跳转到错误报告页面,这份报告里会包括错误点、错误类型、传输的数据和内部源码,这一般是方便开发人员寻找漏洞的功能。服务器是指web服务器,用于向浏览器等web客户端提供网站文档、文件和数据,供用户任意浏览和下载,也就是所说的静态文件。

可以看出三个环节当中开发环境和生产环境的区别最大,Django框架对于这两个环境有不同的配置选项。开发环境中,Django会启动自带的WSGI单线程服务器供开发者使用,不需要再额外配置,并且会自动在每一个功能模块的目录下搜索和调用静态文件。生产环境中,Django则会关闭自带的自动搜索静态文件功能,开发者应将文件统一放置在根目录下供其他高性能服务器调用,Django也提供了对应的收集命令。

明白了环境的不同,那么就要为部署上线的生产环境选择可行方案。通过对比分析已有的Apache、 Nginx 、IIS三大主流服务器,我选择了Nginx作为生产服务器。这是由于其免费开源,占有内存少,并发能力强,适用于Linux系统,具有负载均衡服务,是一种强大的反代理服务器。选定好服务器后,对于使其连接Django还需要网关接口,简单地说是负责双方进行沟通和桥梁和协议。Django自带的是WSGI,是一种通信协议,用于沟通web应用程序(如Django)。还有uwsgi,是一种线路协议,用于与nginx等代理服务器进行通信。最后要提到http,是一种超文本传输协议。而uWSGI则是同时实现WSGI、uwsgi和http等三种协议的web服务器。为了更好说明这些组件的相互作用,请看图 4-1 生产环境示意图。

剩下就是设置搭建uWSGI和Nginx了,读者可以去uWSGI-docs网站的文章[10]了解到具体教程,因为篇幅和内容安排,这里将不做过多叙述。对于本系统而言,结合用途和成本考虑,只搭建测试环境,用于模拟真实的用户体验,其实是与生产环境高度相似的。

图 4-1 生产环境示意图 5.结论 5.1 总结课题及成果 本课题围绕解决代码量统计问题,设计并开发了积码系统。此系统除了具有核心功能-代码量统计报告外,扩展了课程管理,作业管理,自主练习等功能,搭配后台管理系统,并部署云端。这样不仅能够让学生记录自己编程学习的情况,还可以让老师更好地掌握学生学习的进程,总体达到辅助编程学习的效果。

5.2 未来展望 积码系统定位于编程学习辅助工具,现在的核心功能为代码量统计分析。从绪论里提到的判断编程水平的三个维度:编写代码的进度、程序的质量和总代码量,可以找到积码系统未来发展的两个方向。其一,与我校在线判题系统进行信息共享,获取学生在答题过程中的时间和准确率,以评估编写代码的速度和程序的质量。其二,提高程序代码量的判定条件,现在的判定条件是不为空的有效行数,日后还可针对不同的编程语言规则,添加注释行的判定。

除了以上两点,另外未来还可以丰富学习资料功能,比如增加在线视频点播,以及教师视频直播等,检索和收集更多计算机相关知识教程。此外还可增强讨论和问答功能,让学习者们更好地进行交流。

在应用扩展这一方面,我想要提及人工智能技术[11]的API接口[12]应用对于实用型系统软件的重要性。人工智能技术API开发解决了中小平台自主研发技术的问题,让开发者更专注于思考如何将人工智能技术与自己的系统相结合,创造技术更多的应用场景。积码系统本质上偏2B类产品[13],注重的是解决提高学习编程效率的需求,所以围绕提高学习效率,我们可以做出如下构想:一、将语音识别[14]和机器翻译[15]相结合,为视频点播和直播自动生成字幕;
二、通过图像识别[16]和文字识别[17],将编写的代码程序获取,建立数据模型,综合地分析代码程序的质量,给出评定等级和修改建议等。

最后在安全和性能方面再谈及几点。现在系统的使用范围还仅限学校内部,如果在使用过程中觉得对编程学习有一定作用和价值,可以考虑推向校外人士,这时就需要进行系统性能和安全性的提高。如性能而言,可以增加服务器的数量,进行分布式存储,利用负载均衡提高并发量;
安全性则需要增加网络管理员对系统的日常维护与管理,设置蜜罐、监测和添补漏洞等。

参考文献 [1] 蒋宗礼. 基于教学质量国家标准的本科计算机类专业应用型人才培养思考[J]. 中国大学教学,2015.(5):18-21. [2] 张宝元. 基于Django的学生综合成绩管理平台设计与实现[D]. 天津大学, 2016. [3] 杨武帅,万启元,桑贤伯等. 基于Python和Django框架的物联网智能设备管理系统的设计与实现[J]. 中国新技术新产品,2018,(11):13-15. [4] Chen PPS. The Entity-Relationship Model-Toward a Unified View of Data[J]. ACM Transactions on Database Systems,Mar.1976.1:9-36. [5] 严春燕,戴仕明. 基于框架的web前端(Bootstrap和MUI)之比较[J]. 网络安全技术与应用,2017, (4): 83-84. [6] 谈华宇,吴昶成,邱小平.基于Bootstrap框架的动态表单设计与实现[J]. 无线互联科技,2015,41(3):99-100. [7] 胡非,韩永辉,许超,周巧妮.基于Python的可视化工具研究与应用[J]. 工程技术研,究2018,13:25-26 [8] 胡晓燕. 基于Python的可视化数据分析平台设计与实现[J]. 信息与电脑:理论版,2018(17):96-97. [9] 陈衍鹏,杜家兵. 基于框架管理界面自动生成模块的设计与实现[J].自动化与仪器仪表,2018,(5). [10] 使用uWSGI和nginx来设置Django和你的web服务器. https://uwsgi-docs-zh.readthedocs.io/zh_CN/latest/tutorials/Django_and_nginx.html [11] 尹超,马竹娟. 人工智能技术的应用和发展[J]. 赤峰学院学报:自然科学版, 2017,33(5):27-28. [12] 李正,吴敬征,李明树等. API 使用的关键问题研究∗[J]. 软件学报,2018.29(6):1716-1738. [13] 邓晓进,浪鹰. SaaS敲开餐饮8年后:美团成行业公敌,B端竞争模式升级[J].电脑报,2019,(16). [14] 孙阿利. 基于动态贝叶斯网络的音视频语音识别模型研究[D]. 西北工业大学,2007. [15] 王淼. 基于回复式神经网络的机器翻译技术研究及应用[D]. 电子科技大学, 2018. [16] 何平. 基于深度学习的图像识别算法研究[D]. 贵州大学, 2019. [17] 高威威. 基于深度学习的自然场景文字识别[D]. 安徽大学, 2019. 附录:积码系统依赖的工具包 注:下面列出积码系统所依赖的工具包。书写的格式是“工具包名称==工具包版本号”。如下所示:
Django==2.0 Pillow==5.3.0 django-chunked-upload==1.1.3 django-ckeditor==5.9.0 django-js-asset==1.2.2 django-simpleui==3.9 xlrd==1.2.0 PyMysql==0.9.2 Unidecode==1.1.1 pytest-runner==5.2 pyecharts==0.5.11 pyecharts_snapshot==0.1.8 mysqlclient==1.4.6

诚达文秘网 https://www.rk1k.cn Copyright © 2019-2024 . 诚达文秘网 版权所有

Powered by 诚达文秘网 © All Rights Reserved. 备案号:浙ICP备19042126号-1

Top