1.7 Web学生管理系统
1.定义通讯协议
基于前面介绍过的 FLask Web 网站 与 urlib 的访问网站的方法,设计一个综合应用实例。它是一个基于 Web 的学生记录管理程序。
学生的记录包括 id(学号) 、name(姓名) 、grade(成绩),服务器的作用是建立与维护一个Sqllite 的学生数据库 student.db 中的学生记录表 student。
服务器建立一个 Web 网站, 同时提供查询学生记录、增加学生记录、删除学生记录等接口服务。服务器为了与客户端通信,建立一个opt 的参数如下表:
opt值 | 含 义 |
init | 初始化学生表 |
insert | 增加学生 |
delete | 删除学生 |
update | 更改学生 |
select | 查询学生 |
opt 参数值 | 获取学生记录 |
规定如下:
如果客户端向服务器发送 opt="init" ,那么服务器创建 students 表,并返回是否创建成功,如果成功就返回 {"msg":"OK"}
如果客户端向服务器发送 opt="insert" , 同时发送id , name , grade 参数,那么服务器向数据库表插入一条学生记录,并返回是否插入成功信息,如果成功就返回 {"msg":"OK"}
如果客户端向服务器发送 opt="delete" , 同时发送 id 参数,那么服务器从数据库表中删除学号为 id 的一条学生记录,并返回是否删除成功的信息,如果删除成功就返回 {"msg":"OK"}
如果客户端向服务器发送 opt="update" , 同时发送 id 参数,那么服务器从数据库表中更改学号为 id 的一条学生记录,并返回是否更改成功的信息,如果更改成功就返回 {"msg":"OK"}
如果客户端向服务器发送 opt="select" , 同时发送id 参数,那么服务器从数据库表中查询学号为 id 的一条学生记录,并返回是否查询成功的信息,如果查询成功就返回 {"msg":"OK"}
如果客户端不向服务器发送 opt 参数值,那么服务器获取所有的学生记录返回给客户端,如果成功就返回 {"msg":"OK","data":"rows"} , 其中 rows 是学生的记录行的列表。
2.服务器程序
服务器程序server.py如下:
import flask
import sqlite3
import json# 初始化一个Flask对象,参数__name__是程序的名称
app = flask.Flask(__name__)class StudentDB:def __init__(self):self.cursor = Noneself.con = None# 通过学生类打开一个数据库,采用sqlite3.connect来连接def openDB(self):self.con = sqlite3.connect("students.db")# 获取Cursor游标对象,用于执行sql语句并获得结果self.cursor = self.con.cursor()# 关闭连接def closeDB(self):self.con.commit()self.con.close()# 创建一个学生表def initTable(self):res = {}try:self.cursor.execute("create table students (id varchar(16) ""primary key,name varchar(16),grade int)")res["msg"] = "OK"except Exception as err:res["msg"] = str(err)return res# 插入学生def insertRow(self, id, name, grade):res = {}try:self.cursor.execute("insert into students (id,name,grade) ""values(?,?,?)", (id, name, grade))res["msg"] = "OK"except Exception as err:res["msg"] = str(err)return res# 删除学生def deleteRow(self, id):res = {}try:self.cursor.execute("delete from students where id=?", (id,))res["msg"] = "OK"except Exception as err:res["msg"] = str(err)return res# 修改学生def updateRow(self, id):res = {}try:self.cursor.execute("update students set name=?,grade=? where id=?", (id,))res["smg"] = "OK"except Exception as err:res["msg"] = str(err)return res# 获取学生的所有信息def selectRows(self):res = {}try:data = []self.cursor.execute("select * from students order by id")rows = self.cursor.fetchall() # 在 Python 中使用 fetchall() 从数据库文件中提取元素for row in rows:# 每一个学生记录都是一个字典d = {"id": row[0], "name": row[1], "grade": row[2]}data.append(d)res["msg"] = "OK"res["data"] = dataexcept Exception as err:res["msg"] = str(err)return res@app.route("/", methods=["GET", "POST"])
def process():# 获取opt的值opt = flask.request.values.get("opt") if "opt" in flask.request.values else ""res = {}# 创建数据库db = StudentDB()db.openDB()if opt == "init":res = db.initTable()elif opt == "insert":id = flask.request.values.get("id") if "id" in flask.request.values else ""name = flask.request.values.get("name") if "name" in flask.request.values else ""grade = flask.request.values.get("grade") if "grade" in flask.request.values else ""res = db.insertRow(id, name, grade)elif opt == "delete":id = flask.request.values.get("id") if "id" in flask.request.values else ""res = db.deleteRow(id)elif opt == "update":id = flask.request.values.get("id") if "id" in flask.request.values else ""res = db.updateRow(id)else:res = db.selectRows()db.closeDB()return json.dumps(res)if __name__ == '__main__':app.run()
3.客户端程序
客户端程序client.py如下:
import urllib.request
import urllib.parse
import json# 创建一个student的对象
class Student:def __init__(self, id, name, grade):self.id = idself.name = nameself.grade = gradedef show(self):# 打印方法print("%-16s %-16s %-4d" % (self.id, self.name, self.grade))students = []
# server的网址
url = "http://127.0.0.1:5000"# 显示主功能界面
def main():print("=" * 15 + "主界面" + "=" * 14)print("*" * 10 + "1-添加学生信息" + "*" * 10)print("*" * 10 + "2-删除学生信息" + "*" * 10)print("*" * 10 + "3-修改学生信息" + "*" * 10)print("*" * 10 + "4-查询学生信息" + "*" * 10)print("*" * 10 + "5-显示所有学生信息" + "*" * 7)print("*" * 10 + "6-初始化学生列表" + "*" * 8)print("*" * 10 + "0-退出系统" + "*" * 13)print("=" * 33)# 初始化
# 如果客户端向服务端发送opt="init",那么服务器创建students表,并返回是否创建成功,如果成功就返回{"msg":"OK"}
def initialize():st = ""try:content = urllib.request.urlopen(url + "?opt=init")st = content.read()st = json.loads(st.decode())st = st["msg"]except Exception as err:st = str(err)if st == "OK":print("初始成功")else:print(st)return st# 插入学生记录
# 如果客户端向服务器发送opt="insert",同时发送id、name、grade参数,那么服务器向数据库表插入一条学生记录,并返回是否插入成功信息,如果如果成功就返回{"msg":"OK"}
def insertRow():# 获取学生的学号、姓名、成绩id = input("id=")name = input("name=")while True:grade = int(input("grade="))if 0 <= grade <= 100:breakelse:print("无效成绩!\n请重新输入 范围:0~100")if id != "" and name != "":s = Student(id, name, grade)for x in students:if x.id == id:print(id + "已经存在")returnst = ""try:# 调用远程数据st = "id=" + urllib.parse.quote(id) + \"&name=" + urllib.parse.quote(name) + \"&grade=" + str(grade)st = st.encode()content = urllib.request.urlopen(url + "?opt=insert", st)st = content.read()st = json.loads(st.decode())st = st["msg"]except Exception as err:st = str(err)if st == "OK":insertStudent(s)print("添加成功")else:print(st)else:print("学号、姓名不能为空")# 插入学生记录
def insertStudent(s):global studentsi = 0while i < len(students) and s.id > students[i].id:i += 1# 判断表格里面是否存在if i < len(students) and s.id == students[i].id:print(s.id + "已经存在")return Falsestudents.insert(i, s)return True# 删除学生记录
# 如果客户端向服务器发送opt="delete",同时发送id参数,那么服务器从数据库表中删除学号为id的一条学生记录,并返回是否删除成功的信息,如果如果成功就返回{"msg":"OK"}
def deleteRow():global studentsid = input("id=")if id != "":for i in range(len(students)):if students[i].id == id:st = ""try:st = "id=" + urllib.parse.quote(id)st = st.encode()# 找到id就调用urllib.request.urlopencontent = urllib.request.urlopen(url + "?opt=delete", st)st = content.readline()# 通过json解析数据st = json.loads(st.decode())st = st["msg"]except Exception as err:st = str(err)if st == "OK":del students[i]print("删除成功")else:print(st)break# 更新学生信息
def updateRow():pass# 查询学生信息
def selectRow():pass# 读取学生记录
def readStudents():global studentstry:students.clear()content = urllib.request.urlopen(url)data = b"" # 二进制str变量while True:buf = content.read(1024) # 每次读取1024字节内容,并且指针指向末尾if len(buf) > 0:data += bufelse:breakdata = data.decode() # 解码 UTF-8# 反系列结构化的数据data = json.loads(data)if data["msg"] == "OK":data = data["data"] # data["data"]=[row0,row1.row2...]for d in data:# 每个d都是一个字典s = Student(d["id"], d["name"], d["grade"])students.append(s)except Exception as err:print(err)# 显示所有的学生
def listStudents():global studentsprint("%-16s %-16s %-4s" % ("id", "name", "grade"))for s in students:# 调用show函数s.show()try:readStudents()while True:main() # 打印菜单s = int(input("请选择(0,1,2,3,4,5,6):"))if s == 0: # 退出系统breakelif s == 1: # 添加学生信息insertRow()elif s == 2: # 删除学生信息deleteRow()elif s == 3: # 修改学生信息updateRow()elif s == 4: # 查询学生信息selectRow()elif s == 5: # 显示所有学生信息listStudents()elif s == 6:initialize() # 初始化学生列表
except Exception as exp:print(exp)
客户端结果实例:

相关文章:
1.7 Web学生管理系统
1.定义通讯协议基于前面介绍过的 FLask Web 网站 与 urlib 的访问网站的方法,设计一个综合应用实例。它是一个基于 Web 的学生记录管理程序。学生的记录包括 id(学号) 、name(姓名) 、grade(成绩),服务器的作用是建立与维护一个Sqllite 的学生数据库 stu…...
前端教学视频分享(视频内容与市场时刻保持紧密相连,火热更新中。。。)
⚠️获取公众号 本次要想大家推荐一下本人的公众号,在微信中搜索公众号 李帅豪在对话框中输入前端视频四个字即可立即获取所有视频,不收费无广告!!! 本公众号收集了近两年来前端最新最优秀的学习视频,涵盖…...
Docker-consul的容器服务更新与发现
一.Consul概述1.1 什么是服务注册与发现服务注册与发现是微服务架构中不可或缺的重要组件。起初服务都是单节点的,不保障高可用性,也不考虑服务的压力承载,服务之间调用单纯的通过接口访问。直到后来出现了多个节点的分布式架构,起…...
Java笔记-线程中断
线程的中断 1.应用场景: 假设从网络下载一个100M的文件,如果网速很慢,用户等得不耐烦,就可能在下载过程中点“取消”,这时,程序就需要中断下载线程的执行。 2.常用中断线程的方法: 1.使用标…...
js中的自调用表达式
自调用表达式 由函数表达式创建的函数可以自调用,称之为自调用表达式。 语法 由函数表达式创建函数: const myFn function () {let a 100console.log(a);return a } myFn() //调用后执行,输出100表达式后面紧跟 ( ) 则会自动调用: const myFn fu…...
Python操作的5个坏习惯,你中了几个呢?
很多文章都有介绍怎么写好 Python,我今天呢相反,说说写代码时的几个坏习惯。有的习惯会让 Bug 变得隐蔽难以追踪,当然,也有的并没有错误,只是个人觉得不够完美。 注意:示例代码在 Python 3.6 环境下编写 …...
C++并发与多线程编程(3)---线程间共享数据
主要内容:共享数据带来的问题使用互斥量保护数据数据保护的替代方案共享数据带来的问题当涉及到共享数据时,问题可能是因为共享数据修改所导致。如果共享数据是只读的,那么只读操作不会影响到数据,更不会涉及对数据的修改…...
洞察:2022年医疗行业数据安全回顾及2023年展望
过去的2022年,统筹安全与发展,在医疗信息化发展道路中,数据安全不可或缺。这一年,实施五年多的《网络安全法》迎来首次修改,《数据安全法》、《个人信息保护法》实施一周年,配套的《数据出境安全评估办法》…...
多传感器融合定位十五-多传感器时空标定(综述)
多传感器融合定位十五-多传感器时空标定1. 多传感器标定简介1.1 标定内容及方法1.2 讲解思路2. 内参标定2.1 雷达内参标定2.2 IMU内参标定2.3 编码器内参标定2.4 相机内参标定3. 外参标定3.1 雷达和相机外参标定3.2 多雷达外参标定3.3 手眼标定3.4 融合中标定3.5 总结4. 时间标…...
开发微服务电商项目演示(三)
一,nginx动静分离第1步:通过SwitchHosts新增二级域名:images.zmall.com第2步:将本次项目的易买网所有静态资源js/css/images复制到nginx中的html目录下第3步:在nginx的核心配置文件nginx.conf中新增二级域名images.zma…...
C/C++排序算法(二) —— 选择排序和堆排序
文章目录前言1. 直接选择排序🍑 基本思想🍑 具体步骤🍑 具体步骤🍑 动图演示🍑 代码实现🍑 代码升级🍑 特性总结2. 堆排序🍑 向下调整算法🍑 任意树调整为堆的思想&#…...
爬虫笔记之——selenium安装与使用(1)
爬虫笔记之——selenium安装与使用(1)一、安装环境1、下载Chrome浏览器驱动(1)查看Chrome版本(2)下载相匹配的Chrome驱动程序地址:https://chromedriver.storage.googleapis.com/index.html2、学…...
STC15单片机软串口的使用
STC15软串口的使用📖在没有使用定时器资源的情况下,根据波特率位传输时间,利用STC-ISP工具自动计算出位延时函数。 ✨在官方所提供的库函数中位传输时间函数,仅适用于使用波特率为:9600的串口数据传输: void BitTime(…...
Ansible的脚本------playbook剧本
一、剧本的前置知识点1、主机清单ansible默认的主机清单是/etc/ansible/hosts文件主机清单可以手动设置,也可以通过Dynamic Inventory动态生成一般主机名使用FQDNvi /etc/ansible/hosts [webserver] #使用方括号设置组名 www1.example.org #定…...
实验5-计算中值及分治技术
目录 1.寻找中位数(利用快速排序来寻找中位数) 2.分治方法求数组的和 3.合并排序...
dbeaver从excel导入数据笔记
场景 有excel的数据,需要做到数据库里。 方案一: 开发代码来实现。缺点是需要开发成本。 方案二: 数据库导入工具导入。不用开发,相对快速一些。 这里说下数据库工具导入。 操作过程 1、拿到excel数据文件,根据标题…...
PyTorch学习笔记:nn.MarginRankingLoss——排序损失
PyTorch学习笔记:nn.MarginRankingLoss——排序损失 torch.nn.MarginRankingLoss(margin0.0, size_averageNone, reduceNone, reductionmean)功能:创建一个排序损失函数,用于衡量输入x1x_1x1与x2x_2x2之间的排序损失(Ranking Loss)&…...
【JavaScript】34_Date对象 ,日期的格式化
8、Date Date 在JS中所有的和时间相关的数据都由Date对象来表示 对象的方法: getFullYear() 获取4位年份 getMonth() 返当前日期的月份(0-11) getDate() 返回当前是几日 getDay() 返回当前日期是周几(0-6) 0表示周日…...
计算机视觉 对比学习13篇经典论文、解读、代码
为了快速对 机器视觉中的对比学习有一个快速了解,或者后续复习,此处收录了 13篇经典论文、一些讲解地较好的博客和相应的Github代码,用不同颜色标记。 对比学习 13篇经典论文 论文代码和博客http://www.webhub123.com/#/home/detail?p…...
MySQL 选择数据库
在你连接到 MySQL 数据库后,可能有多个可以操作的数据库,所以你需要选择你要操作的数据库。 在 MySQL 中就有很多系统自带的数据库,那么在操作数据库之前就必须要确定是哪一个数据库。 在 MySQL 中,USE 语句用来完成一个数据库到…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...
《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案
这个问题我看其他博主也写了,要么要会员、要么写的乱七八糟。这里我整理一下,把问题说清楚并且给出代码,拿去用就行,照着葫芦画瓢。 问题 在继承QWebEngineView后,重写mousePressEvent或event函数无法捕获鼠标按下事…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...
