用Flask+Bootstrap+Restful开发学校管理系统

Flask是一个微框架,有众多围绕其开发的辅助库,例如:Jinja2模板,Restless接口库、SQLAlchemy对象关系模型等。

1 系统概览

1.1 项目来源及功能

学校管理系统项目的名称为XUEMC,基于Flask框架及其周边的Python库开发而成。在前端页面设计方面引用了开源的UI框架AdminLTE,该框架提供了一套基于Booststrap的网站HTML模板,使得没有前端设计经验的开发者也能快速开发出优雅的响应式页面。AdminLTE的网址为

https://almsaeedstudio.com

学校管理系统的目标是:建立一个用于管理学校和培训机构信息的信息库,使各种第三方应用能够通过Restful接口获取信息。作为平台管理员的维护工具,它提供了Web页面用于信息录入及查询。学校管理系统的主页面如下:

该页面主要由两部分组成,即左侧的导航栏和右侧的学校显示页面。左侧的导航栏中有8个功能链接,分别如下:

所有学校:黄色标签显示学校数量,单击后在右侧区域显示所有学校信息的分页表格

所有培训结构:黄色标签显示系统中培训机构的数量,单击后在右侧区域显示所有培训机构的页面表格。

公告列表:黄色标签显示公告数量,单击后在右侧区域显示所有公告的分页表格。

新建学校:单击后进入学校信息录入及新建页面

新建培训机构:单机后进入培训机构信息录入及新建页面。

新建公告:单击后进入公告录入及新建页面。

新建用户账号:单击后进入新建账号页面。

以上8个功能可以分为两组,实体列表页面(前四项)和实体录入页面(后四项),这是因为网站中把类似的设计方法用在了不同的信息实体上。另外,在左侧导航栏的最上方有一个搜索区域,用户可以直接通过该区域输入名称进行实体模糊搜索。

1.2 项目安装

对XUEMC项目建议使用PostgreSQL数据库,所以在安装项目代码前请确保该数据库正常安装。

PostgreSQL数据库安装

以Ubuntu Linux为例,安装PostgreSQL数据库的命令是:

系统会提示安装所需的磁盘空间,输入"y",按照提示逐步完成安装。安装完毕后,系统会创建一个数据库超级用户"postgres",密码为空。可以用如下命令设置postgres用户的新密码:

此后,需要为Tmitter项目新建一个数据库,命令如下:

windows系统

访问 PostgreSQL 官方网站:PostgreSQL: The world's most advanced open source database

选择合适的版本

下面以Ubuntu Linux 14.04为例演示XUEMC系统的安装过程。

①安装代码及依赖库

将项目配套的源文件复制到目标计算机路径中,比如~/project目录。复制完成后,找到项目中的requirement.txt文件,其中包括所有本项目依赖的组件库。

通过如下命令可以对它们实现一键安装:

②安装和配置数据库

PostgreSQL安装完成后用如下命令新建登录角色和数据库:

python 复制代码
psql -U xuemc -d postgres -h 127.0.0.1  # 以xuemc的身份登录
CREATE DATABASE xuemc_bd;  # 创建新的数据库
\q  # 退出
psql -U xuemc -d xuemc_bd -h localhost # 重新登录

之后执行数据库安装脚本DB/xuemc_db.sql,该文件位于项目DB/目录中:

其中,localhost是主机的IP地址、xuemc是刚刚新建的Postgres登录用户名、xuemc_db是数据库的名称。执行过程中需要输入用户xuemc的密码。

为了在新建的数据库xuemc_db中创建所需的表结构、视图、函数等对象。这些对象是根据业务需求设计的,用于存储和管理数据。

安装完成后可在本项目中配置数据库的连接参数,在web/app.py文件中找到如下部分并修改:

将其中的USER、PASS、DBNAME分别修改为安装数据库时的用户名、密码、数据库名称。

③启动

项目用uWSGI进行运行管理,其配置文件为项目文件夹中的uwsgi.ini,内容为:

修改其中的http、venv、chdir3个参数分别为真实的监听地址、虚拟环境路径、项目路径。

如果修改了uwsgi.ini文件中的主机IP与端口,则要对web/Logic/restful.py文件中的如下配置做相应修改:

保存文件后通过如下命令即可启动站点:

此时打开浏览器访问http://127.0.0.1:5010

1.3 代码结构

xuemc项目整合了各种第三方资源,包括使用开源UI库AdminLTE、调用SQLAlchemy数据模型、Restful接口调用等,学习如何优雅地讲这些资源和代码整合在一起能够大大提高初学者的设计能力。

xuemc项目的代码结构如下:

项目主目录的文件有4个主要部分,即数据层包DB\、工具包Utils\、网站包web\和启动文件run.py:

  • 数据层与网站业务的逻辑相互独立,在包DB\中管理所有关系数据对象模型。如果有费关系数据如MongoDB等,也可放在DB\包中。
  • 在包Utils\中存放工具箱代码,例如发送短信、编码转换等。Utils\包中的代码一般可在不同的项目之间共享。
  • 在包web\中部署了开源UI框架(AdminLTE/)、网站逻辑层(Logic/)、网站UI文件(plugins/、statics/)和网站MVC架构代码文件(app.pyforms.py、templates/、views/).
  • 启动文件run.py完成各模块的加载工作,uwsgi.ini中的下列参数指定通过run.py完成站点加载:

2 数据模型设计

在大型应用开发的初期,数据模型设计是非常重要的工作。本节解析xuemc项目的数据模型及其使用SQLAlchemy的物理设计。

2.1 E-R图设计

E-R图是最有用的数据库建模工具,通过它可以分析系统中的实体、属性及实体之间的关系。xuemc系统的核心实体建模如下图所示:

xuemc系统中的学校实体分为两种:培训机构(institution)和普通学校(school),上图中的所有实体均围绕两者展开,可以分为5个层:

①第一层:5个元数据实体,包括收费类型(feetype)、年龄段(agespan)、所在区县(area)、教学特色(feature)、学校类型(schooltype)。下两层实体与这些实体建立多对一或多对对关系。

②第二层:两个核心实体:培训机构和学校,每个实体中的字段用于存放实体的相关信息,比如招生年龄(通过agespan_id关联到年龄段实体)、地址(address)、联系方式(telephone)等。

③第三层:是第二层实体的附属实体和关系实体。institutionmage和schoolimage分别是第2层实体的附属多对一实体,用于保存每个机构、学校的图片路径信息。而insitution_feature和school_feature是第2层实体与第1层feature实体进行关联的多对多关系实体。

④xuemc中还管理了公告和用户这两类信息,他们的数据建模如下图所示,这两组实体相对独立,只进行了简单的信息保存。bulletin是公告主表,用于保存公告标题、时间、内容、来源、作者等信息。bulletinimage是其辅助实体,保存公告相关的图片信息。account是用户实体,保存用户的注册手机号、用户名、密码、注册时间等。其辅助实体terminal用于管理用户的登录设备。比如,同一个账号在不同的手机上登录时会在terminal实体中产生多条记录。

xuemc项目中的账号(account)实体仅仅用作在Restful接口中提供用户注册功能,并没有基于账号进行任何权限控制,即所有账号都可以查询、修改任何实体数据。

2.2 SQLAlchemy建模

完成E-R图建模后,就可以直接用SQLAlchemy进行模型实现了。在suemc项目中物理模型代码保存在DB/orm.py文件中

①账号及登录设备

上图中的账号及登录设备实体可以映射为如下两个SQLAlchemy类。

通过这种方式为E-R图中的实体都定义了对应的db.Model子类Account和Terminal,并且通过类属性定义了每个模型中列的具体类型、主外键约束、实体间的关联关系等。在Terminal中定义了具有backref参数的relationship属性,所以Account和Terminal实例之间可以互相引用,比如:

②系统元数据

元数据(Metadata),又称为中介数据,主要是描述系统中实体数据属性(property)的信息,用来支持资源查找、记录等功能。项目的元数据在执行安装脚本xuemc_db时一次性写入,在系统运行的过程中不会发生变化。

xuemc系统的元数据表应该包括年龄段定义、区县定义等5个实体类。

③学校信息模型

公告、培训机构和学校实体及围绕它们的关系实体代码如下:

读者需要重点关注和维护它们之间关系的db.relationship()属性的用法,通过它定义了Bulletin与BulletinImage、Institution与InstitutionImage、School与SchoolImage之间的相互引用属性,并且其中的cascade="all, delete-orphan"定义了级联删除属性,即当删除主模型(Bulletin、Institution、School)中的记录时,副模型中的记录也自动删除。

3 响应式页面框架设计

xyemc系统的页面框架是基于开源框架AdminLTE开发而成的,本节解析其响应式的页面结构,使Web开发初学者能够理解前端设计方法并能改造已有的页面框架。

3.1 基模板组件引用

为了保证各子页面的风格一致,所有网站项目开发中都有一个页面基模板。基模板定义了站点的标题栏、导航、页脚等基本元素。

基于Booststrap、jQuery等公共前端组件库进行页面开发已经成为业界的主流,他们使得开发者能够站在巨人的肩膀上,避免了很多基层工作。xuemc项目的基模板文件为web/templates/base.html,其主要工作是加载页面元素用到的Booststrap、Font Awesome、Ionicons等组件库,并实现导航栏。

基模板中的页面框架和组件的引用代码如下:

代码中在<head>和<body>标签内都有大量的第三方组件引用,其中<head>是对层叠样式表CSS的组件引用;<body>是对JavaScript的脚本引用。有了这些组件,就可以较容易地实现HTML5页面的个性化UI元素。

代码中的所有引用路径(href和src)都以/bd/web的形式为开头,这是因为在项目Flask的视图代码中定义了/bd/web路径文件的映射地址,代码如下:

所有对以/bd/web为开头的地址的访问有函数rootDir_web()进行处理。处于安全原因,该函数不允许客户端直接读取任何.py代码文件;所有其他类型的文件将被映射到项目的web/子目录中。因此,对/db/web/AdminLTE/bootstrap/css/bootstrap.min.css的访问将被映射为服务器项目中的web/AdminLTE/bootstrap/css/bootstrap.min.css文件;/bd/web/static/base.js被映射为web/static/base.js文件。

3.2 响应式导航

在基模板web/templates/base.html中还完成了站点导航栏的设计。本项目使用了HTML5中的新标签<aside>,结合sidebar.less中的响应式属性,实现了可以适应不同浏览器的大小,进行自动伸缩的边侧导航栏。导航栏部分的代码如下:

导航栏内容全部包含在<aside class="main-sidebar">标签中,其中<aside>定义这是一个边侧区域,而class="main-sidebar"定义了该区域随着浏览器可见区域的大小自动变化。

在<div class="user-panel">区域中定义了登录显示区域,在其中显示了一些静态信息,比如状态、头像图片等。其中用<img class="img-circle">实现了显示圆形图片的方法。

在<form action="#" method="get" class="sidebar-form">标签中实现了搜索工具界面,当用户点击"提交"按键时,会向当前URL发送GET请求,并传入查询字符串的参数q。

用以下格式为每个页面定义一个导航链接,其中<a href="...">标签定义目标地址和显示文字;{% if ...%}标签组显示数量属性。

4 新建学校

在系统中逐个新建学校和培训机构的节本信息是本系统在实际应用中的第一项工作,所以这里是以新建学校为例学习xuemc项目的新建学校、机构、公告功能。

4.1 WTForm表单

项目通过HTML表单的方式让管理员在网页中输入学校信息。信息的输入界面如下图所示。

表单中包含所有在E-R中定义的学校实体属性。在web/forms.py文件中定义了项目的所有WTForm子类,学校的表单类如下:

表单类继承自flask_wtf.Form基类,SchoolForm的每个类属性定义了一个表单中的输入项目,类属性的第1个参数是输入项在网页中的显示字符串。类属性按类型可分为以下几类。

对于选择类型字段,通过配置字段的choices属性设置字段的可选项,比如:

所在区县、学校类型、教学特色等是系统的元数据。在代码logic.py中通过SQLAlchemy从数据库中加载所有的元数据到变量g_choices_xxx中;在views.py中为每个实例化的表单类定义器选择字段的choices属性。

4.2 视图及文件上传

使用SchoolForm的视图函数是view.py中的view_school(),其关键代码如下:

4.3 响应式布局

在新建学校的页面上,项目使用了Bootstrap的响应式布局之法。该方法将页面纵向分为12个栅格,用不同大小的浏览器可视区域中元素所占的栅格数量进行响应式布局。

比如对于<div class="col-lg-5 col-xs-10">,标签定义该内容在大屏幕(lg)时所占用的栅格数是5;在小屏幕(xs)时所占用的栅格数是10。这样,在大屏幕下<div>在一行中可以显示两个(两个占用10栅格,小于12栅格);而小屏幕下<div>只能够显示1个。

在页面模板web/templates/views_school.py中,通过Bootstrap类型实现对表单项目的响应式布局。

模板逻辑相当简单,即将试图传入的form参数中的字段属性逐个用{{render_field}}标签渲染到页面中。

5 学校管理

通过开发学校管理界面,可以熟练掌握查询字符串的处理、分页试图、修改即删除操作的常用设计方法。

5.1 查询试图

学校管理功能围绕着主页的学校查询及显示功能展示,该页面通过Restful接口完成数据查询功能,xuemc的数据流程如下图所示,xuemc站点为第三方App和xuemc页面提供了统一的Restful1接口用于信息查询,同时通过SQLAlchemy orm实现数据的增、删、改操作。

这样做的好处是对查询操作提供了唯一的接口,以便集中实现分页、数据筛选等开发工作。同时,避免让第三方App通过Restful接口对网站数据进行修改。

学校管理通过页面/bd/view_schools完成,该页面对所有学校的信息进行分页显示,并且提供按名称筛选功能,试图函数如下:

解析:

  • 用request.args.get()函数从查询字符串中获取页面(page)和查询字符串(q)。如果没有提供page,则默认显示第1页。
  • 用restful.GetSchool()函数从Restful接口中获取查询数据,该函数内容如下:

用requests.get()函数可以通过HTTP访问Restful接口,并通过json.loads()函数解析收到的学校数据。

  • 用GetSchoolFormById()函数为每个查询到的学校新建一个SchoolForm实例,保存在列表schoolforms中,函数如下:
  • 如果是一次通过delete按钮提交的Post请求,则通过ORM模块删除相关数据。
  • 用restful.GetPagingFormResult()函数获取学校实体的分页信息,即生成一个paging对象,里面包含总页面、当前页、开视页、结束页等信息。代码如下:
  • 通过渲染模板view_schools.html显示页面。

5.2 分页模板

学校管理的模板文件主要用于将所有元素显示在网页中,并为每个学校实体提供修改、删除链接。模板文件web/templates/view_schools.html的内容如下:

除了若干用于布局和CSS样式设定的<div>标签,本模板主要由两部分组成;一个是学校显示区域,另一个是分页区域,解析如下:

  • 在学校显示区域通过{%for f in forms %}标签组为每个学校建立一个<form>标签。
  • 在显示学校的名字时,用<a href="/bd/view_school?id={{f.id.data}}">{{f.name.data}}</a>提供到该学校修改页面的链接。
  • 在每个学校的<form>中提供一个删除按钮用于删除该学校。为<form>标签设置onsubmit属性,使得用户单击时能够弹出二次确认框。
  • 用javascript:genPagingRef()函数分贝显示首页、当前上下5页、末页的链接数字。该工具函数位于脚本web/static/base.js中,内容如下:

该函数使得网站在用查询参数搜索页面结果后,仍能按该查询参数在分页之间导航。

6 Restful接口

本节学习Restful的概念和在Flask中用Restless插件快速开发的Restful接口技术。

6.1 Restful概念

Rest即表述性状态传递,是一种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可伸缩性。遵循Rest架构风格的网络接口被称为Restful接口。

Restful接口围绕着网络资源及其动作展开。所谓"资源"就是网络上的一个实体,或者说是网络上的一个具体信息。资源可以是一个文本、一张图片、一首歌曲,在本章的xuemc站点中,所有学校、培训机构、公告都是一种网络资源。

在开发者进行良好设计的前提下,任何网络操作都可以被抽象成网络资源的CRUD动作。Restful将对网络资源的操作抽象为用HTTP的GET、POST等谓词表达的形式,他们的调用形式如下。

6.2 Restless插件

Restless是一个基于SQLAlchemy的Restful API快速开发插件,简单配置它就可以实现功能全面的Restful接口。Restless在使用pip工具进行安装后即可使用。

①基本使用

通过如下例子演示Restless的接口编程

通过上述代码已经开发了一个具备对pandas资源进行查询、新增、删除Restful接口的网站。其中内的关键如下:

②定制接口

为了提供更加灵活的定制功能,前例中的manager.create_api()函数具有更多的可选参数,常用的如下:

③回调函数原型

6.3 开发Restful接口

在xuemc项目中,所有Restful接口通过Restless组件实现。由于只是按照Restless插件的要求执行配置工作,因此相关代码都保存在项目的主文件run.py文件中。

除了逐个配置每个SQLAlchemy资源的开发接口及其地址,上述代码还通过preprocessors和postprocessers实现了用户注册短信认证和默认图片的设置功能。

①用户注册

用户注册的功能和流程如下

用户通过向服务器发送POST、Account请求提交注册要求,并通过PATCH、Account请求提交注册码。因此在实现这两个Restful接口时,需要添加特殊逻辑以实现短信验证功能,具体如下:

②默认图片设置

系统还对orm.Bulletin、orm.Institution、orm.School 3个资源的GET_SINGLE和GET_MANY请求都实现了postprocessors回调,即post_get_one()和post_get_many()函数,用来为没有图片的公告、培训机构、学校配置一个默认图片。

函数post_get_one()和post_get_many()都对即将返回给客户端的资源对象调用了logic.SetDefaultImage()函数,函数如下:

该函数通过检查资源对象中的图片属性判断资源的类型,并对图片属性的列表长度为0的对象设置默认的图片名。

相关推荐
FL16238631292 小时前
基于Python+Flask+MediaPipe实现疲劳和分心驾驶实时检测计算机视觉的驾驶员危险行为检测系统源码+项目说明
python·计算机视觉·flask
yuanpan2 小时前
Python 开发一个简单演示网站:用 Flask 把脚本能力扩展成 Web 应用
前端·python·flask
源码之家21 小时前
计算机毕业设计:Python农产品销售数据可视化分析系统 Django框架 数据分析 可视化 大数据 大模型 机器学习(建议收藏)✅
python·信息可视化·数据分析·django·flask·课程设计
河阿里1 天前
Redis:命令行基础语法与实战
数据库·redis·bootstrap
源码之家1 天前
计算机毕业设计:Python渔业资源数据可视化分析大屏 Flask框架 数据分析 可视化 数据大屏 大数据 机器学习 深度学习(建议收藏)✅
人工智能·python·信息可视化·数据挖掘·数据分析·flask·课程设计
源码之家1 天前
计算机毕业设计:Python降水量分析与预警平台 Flask框架 数据分析 可视化 大数据 AI 大模型 爬虫 数据大屏(建议收藏)✅
人工智能·python·信息可视化·数据分析·django·flask·课程设计
zzh0812 天前
NoSQL之Redis配置与优化
redis·bootstrap·nosql
龙腾AI白云3 天前
大模型在天文科研中的应用:天体数据分析
大数据·flask·逻辑回归·pygame
亚空间仓鼠3 天前
NoSQL数据库Redis(三):主从复制
redis·bootstrap·nosql