flask实现简易图书管理系统
项目结构

技术选型
flask 做后端, 提供数据和渲染html
暂时没有提供mysql, 后续会更新操作mysql和样式美化的版本
起一个flask服务
flask是python的一个web框架, 下面演示如何提供http接口, 并返回json数据

main.py
# flask创建http接口
from flask import Flask, request, jsonify,render_template
# 支持flask跨域
from flask_cors import CORS
# 创建flask服务
app = Flask(__name__)
CORS(app, resources=r'/*') # 注册CORS, "/*" 允许访问域名所有api # 首页
@app.route('/',methods=['get'])
def index():# 自动在templates里找对应名称的文件return jsonify({"msg":"hello"})if __name__ == "__main__":# 运行web服务app.run(host='0.0.0.0', port=10086)
此时打开终端, 运行

python main.py
打开浏览器, 输入 http://localhost:10086/

渲染模板
flask可以渲染html文件(自动往项目根目录的templates里找), 并往里面填数据

main.py
# flask创建http接口
from flask import Flask, request, jsonify,render_template
# 支持flask跨域
from flask_cors import CORS
# 创建flask服务
app = Flask(__name__)
CORS(app, resources=r'/*') # 注册CORS, "/*" 允许访问域名所有api # 首页
@app.route('/',methods=['get'])
def index():# 自动在templates里找对应名称的文件return render_template('index.html',msg="hello world")if __name__ == "__main__":# 运行web服务app.run(host='0.0.0.0', port=10086)
index.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body>{{msg}}
</body>
</html>
浏览器

用对象数组来存放图书数据
main.py
通过模板渲染传递books到html里
# flask创建http接口
from flask import Flask, request, jsonify,render_template
# 支持flask跨域
from flask_cors import CORS
# 创建flask服务
app = Flask(__name__)
CORS(app, resources=r'/*') # 注册CORS, "/*" 允许访问域名所有api # 暂时代替数据库
books = [{"id":'1',"name":"hello world","author":"迭名","desc": "程序员入门第一本书","price": 11.99},{"id":'2',"name":"0基础学it","author":"xx程序员","desc": "某培训机构精心出品教程","price": 99.98},
]# 首页
@app.route('/',methods=['get'])
def index():# 自动在templates里找对应名称的文件return render_template('index.html',books=books)if __name__ == "__main__":# 运行web服务app.run(host='0.0.0.0', port=10086)
index.html
html接收flask后端传来的数据, 渲染到table里
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<!-- 加样式,居中 -->
<style>* {margin: 0 auto;}
</style><body><br><table border="1"><thead><tr><th>书名</th><th>作者</th><th>描述</th><th>价格</th><th>操作</th></tr></thead><tbody>{% for book in books %} {# 遍历 books 变量 #}<tr id={{book.id}}><th>{{book.name}}</th><th>{{book.author}}</th><th>{{book.desc}}</th><th>{{book.price}}</th><th><button id={{book.id}}>删除</button><a href='http://localhost:10086/uptbook?id={{book.id}}'>修改</a></th></tr>{% endfor %} {# 使用 endfor 标签结束 for 语句 #}</tbody></table><br>
</body></html>
查看效果

添加图书
使用a标签请求flask后端, flask后端返回html模板, 实现跳转添加页面(add.html)
这里add.html是在book下, 这是因为如果还有别的服务(比如用户的crud), 可以通过不同文件夹区分模块

添加两个接口, 我们的id就用book对象在books数组里的下标(索引/序号), 添加就直接append添加到books数组的末尾
# 跳转添加页面
@app.route('/addbook',methods=['get'])
def addbook_html():# 自动在templates里找对应名称的文件return render_template('book/add.html')# 添加
@app.route('/addbook',methods=['post'])
def addbook(): # 获取json数据book = request.get_json() book['id']= str(len(book)-1) books.append(book)return jsonify({"books":books})
main.py
# flask创建http接口
from flask import Flask, request, jsonify,render_template
# 支持flask跨域
from flask_cors import CORS
# 创建flask服务
app = Flask(__name__)
CORS(app, resources=r'/*') # 注册CORS, "/*" 允许访问域名所有api # 暂时代替数据库
books = [{"id":'1',"name":"hello world","author":"迭名","desc": "程序员入门第一本书","price": 11.99},{"id":'2',"name":"0基础学it","author":"xx程序员","desc": "某培训机构精心出品教程","price": 99.98},
]# 首页
@app.route('/',methods=['get'])
def index():# 自动在templates里找对应名称的文件return render_template('index.html',books=books)# 跳转添加页面
@app.route('/addbook',methods=['get'])
def addbook_html():# 自动在templates里找对应名称的文件return render_template('book/add.html')# 添加
@app.route('/addbook',methods=['post'])
def addbook(): # 获取json数据book = request.get_json() # 用数组下标表示idbook['id']= str(len(book)-1) # 添加到books末尾books.append(book)return jsonify({"books":books})if __name__ == "__main__":# 运行web服务app.run(host='0.0.0.0', port=10086)
index.html
我们使用axios(js的一个库)来发送http请求
<!-- 引入axios发送请求给后端 -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
发送请求前, 通过input框的value获取数据, 然后axios发送post请求, 并传递一个json对象给后端
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><form id="form"><lable>书名</lable><input type="text" name="book-name" id="book-name"><label>作者</label><input type="text" name="book-author" id="book-author"><label>描述</label><input type="text" name="book-desc" id="book-desc"><label>价格</label><input type="text" name="book-price" id="book-price"><button type="submit">提交</button></form><!-- 引入axios发送请求给后端 --><script src="https://unpkg.com/axios/dist/axios.min.js"></script><script>const addform = document.querySelector("#form")const bookName = document.querySelector("#book-name")const bookDesc = document.querySelector("#book-desc")const bookAuthor = document.querySelector("#book-author")const bookPrice = document.querySelector("#book-price")addform.addEventListener("submit", function (e) {e.preventDefault();// console.log(bookName.value);// 发送请求给后端axios.post('http://localhost:10086/addbook',// 传递json数据给后端{name: bookName.value,author: bookAuthor.value,desc: bookDesc.value,price: bookPrice.value})// axios请求完成后.then((res) => {// 后端处理完请求,axios拿到的结果console.log(res);alert('添加成功')// 跳转首页window.location.href = 'http://localhost:10086/'})})</script>
</body></html>
查看效果




删除图书
我们通过axios发送delete请求给后端, 同时传递id, 后端遍历books, 找到对应id的元素下标, 然后删除
main.py
# flask创建http接口
from flask import Flask, request, jsonify,render_template
# 支持flask跨域
from flask_cors import CORS
# 创建flask服务
app = Flask(__name__)
CORS(app, resources=r'/*') # 注册CORS, "/*" 允许访问域名所有api # 暂时代替数据库
books = [{"id":'1',"name":"hello world","author":"迭名","desc": "程序员入门第一本书","price": 11.99},{"id":'2',"name":"0基础学it","author":"xx程序员","desc": "某培训机构精心出品教程","price": 99.98},
]# 首页
@app.route('/',methods=['get'])
def index():# 自动在templates里找对应名称的文件return render_template('index.html',books=books)# 跳转添加页面
@app.route('/addbook',methods=['get'])
def addbook_html():# 自动在templates里找对应名称的文件return render_template('book/add.html')# 添加
@app.route('/addbook',methods=['post'])
def addbook(): # 获取json数据book = request.get_json() # 用数组下标表示idbook['id']= str(len(book)-1) # 添加到books末尾books.append(book)return jsonify({"books":books})# 删除
@app.route('/delete',methods=['delete'])
def delbook():id = request.args.get('id')# 下标index = -1# 遍历,找到id相同的元素for i in range(len(books)):if books[i]['id'] == id:# 记录元素下标index = i# id不是-1表示有找到要删除的元素if i != -1:# 删除books.remove(books[index])return jsonify({'books': books})else:return jsonify({'books': books})if __name__ == "__main__":# 运行web服务app.run(host='0.0.0.0', port=10086)
index.html
我们在渲染table的时候, 将每行(tr标签)的id设为book的id, 删除时, 可以通过tr的id获取要删除的book的id, 实现删除特定的book
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<!-- 加样式,居中 -->
<style>* {margin: 0 auto;text-align: center;}
</style><body><br><table border="1"><thead><tr><th>书名</th><th>作者</th><th>描述</th><th>价格</th><th>操作</th></tr></thead><tbody>{% for book in books %} {# 遍历 books 变量 #}<tr id={{book.id}}><th>{{book.name}}</th><th>{{book.author}}</th><th>{{book.desc}}</th><th>{{book.price}}</th><th><button id={{book.id}}>删除</button><a href='http://localhost:10086/uptbook?id={{book.id}}'>修改</a></th></tr>{% endfor %} {# 使用 endfor 标签结束 for 语句 #}</tbody></table><br><a href="http://localhost:10086/addbook">添加图书</a><!-- axios,可以发送请求给后端 --><script src="https://unpkg.com/axios/dist/axios.min.js"></script><script>// 按钮const btns = document.querySelectorAll('th > button')// 遍历btns.forEach((b) => {console.log(b.id);// 给按钮添加click事件b.addEventListener('click', function (e) {// todo 弹出确认框,是否删除// 删除axios.delete(("http://localhost:10086/delete?id=" + b.id)).then((res) => {if (res.status == 200 && res.data) {// 刷新页面location.reload();alert('删除成功')} else {alert('删除失败')}})})})</script>
</body></html>
查看效果



修改图书信息

前端点击修改后跳转修改页面
<a href='http://localhost:10086/uptbook?id={{book.id}}'>修改</a>
main.py
# flask创建http接口
from flask import Flask, request, jsonify,render_template
# 支持flask跨域
from flask_cors import CORS
# 创建flask服务
app = Flask(__name__)
CORS(app, resources=r'/*') # 注册CORS, "/*" 允许访问域名所有api # 暂时代替数据库
books = [{"id":'1',"name":"hello world","author":"迭名","desc": "程序员入门第一本书","price": 11.99},{"id":'2',"name":"0基础学it","author":"xx程序员","desc": "某培训机构精心出品教程","price": 99.98},
]# 首页
@app.route('/',methods=['get'])
def index():# 自动在templates里找对应名称的文件return render_template('index.html',books=books)# 跳转添加页面
@app.route('/addbook',methods=['get'])
def addbook_html():# 自动在templates里找对应名称的文件return render_template('book/add.html')# 添加
@app.route('/addbook',methods=['post'])
def addbook(): # 获取json数据book = request.get_json() # 用数组下标表示idbook['id']= str(len(book)-1) # 添加到books末尾books.append(book)return jsonify({"books":books})# 删除
@app.route('/delete',methods=['delete'])
def delbook():id = request.args.get('id')# 下标index = -1# 遍历,找到id相同的元素for i in range(len(books)):if books[i]['id'] == id:# 记录元素下标index = i# id不是-1表示有找到要删除的元素if i != -1:# 删除books.remove(books[index])return jsonify({'books': books})else:return jsonify({'books': books})# 跳转修改页面
@app.route('/uptbook',methods=['get'])
def uptbook_html():id = request.args.get('id') book = {}for b in books: if b['id'] == id:book = breturn render_template('book/update.html',book=book)# 修改
@app.route('/uptbook',methods=['patch'])
def uptbook():id = request.args.get('id') book = request.get_json() index = -1for i in range(len(books)): if books[i]['id'] == id:index = iif index == -1:return jsonify({"books":books})else: if(book['name']!=None):books[index]['name'] = book['name']if(book['author']!=None):books[index]['author'] = book['author']if(book['desc']!=None):books[index]['desc'] = book['desc']if(book['price']!=None):books[index]['price'] = book['price']return jsonify({"books":books}) if __name__ == "__main__":# 运行web服务app.run(host='0.0.0.0', port=10086)
update.html
和添加图书页面基本相同
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><!-- 自定义属性,值为book.id --><form id="form" data-id={{book.id}}><lable>书名</lable><input type="text" name="book-name" value={{book.name}} id="book-name"><label for="">作者</label><input type="text" name="book-author" value={{book.author}} id="book-author"><label for="">描述</label><input type="text" name="book-desc" value={{book.desc}} id="book-desc"><label for="">价格</label><input type="text" name="book-price" value={{book.price}} id="book-price"><button type="submit">提交</button></form><script src="https://unpkg.com/axios/dist/axios.min.js"></script><script>const uptform = document.querySelector("#form")const bookName = document.querySelector("#book-name")const bookDesc = document.querySelector("#book-desc")const bookAuthor = document.querySelector("#book-author")const bookPrice = document.querySelector("#book-price")// 自定义属性 const id = uptform.dataset.iduptform.addEventListener("submit", function (e) {e.preventDefault();// console.log(bookName.value);// 发送请求给后端axios.patch(("http://localhost:10086/uptbook?id=" + id), {name: bookName.value,author: bookAuthor.value,desc: bookDesc.value,price: bookPrice.value}).then((res) => {console.log(res);alert('修改成功')// 跳转回首页window.location.href = 'http://localhost:10086/'})})</script>
</body></html>
查看效果




完结, 恭喜
相关文章:
flask实现简易图书管理系统
项目结构 技术选型 flask 做后端, 提供数据和渲染html 暂时没有提供mysql, 后续会更新操作mysql和样式美化的版本 起一个flask服务 flask是python的一个web框架, 下面演示如何提供http接口, 并返回json数据 main.py # flask创建http接口 from flask import Flask, request, jso…...
2021 年全国大学生物联网设计竞赛(华为杯)全国总决赛获奖名单
由全国高等学校计算机教育研究会主办,上海交通大学承办,华为技术有限 公司协办,中国电信天翼物联、中国移动中移物联网、霍尼韦尔 Tridium、CSA 联盟、新大陆、德州仪器 (TI)、百度、机械工业出版社华章公司联合支持的 2021 全国大学生物联网…...
操作系统复习2.3.5-管程
引入管程 PV操作困难,容易书写出错,引入管程,作为一种高级同步机制 组成 局限于管程的共享数据结构说明对该数据结构进行操作的一组过程对局部于管程的共享数据结构设置初始值的语句管程有一个名字 基本特征 局限于管程的数据只能被局限…...
List Set Map Queue Deque 之间的区别是什么?
List Set Map Queue Deque 之间的区别是什么? 1. Java 集合框架有那些接口?2. List Set Map Queue Deque 之间的区别是什么? 1. Java 集合框架有那些接口? List、Set、Map、Queue、Deque 2. List Set Map Queue Deque 之间的区别…...
unity行为决策树实战详解
一、行为决策树的概念 行为决策树是一种用于游戏AI的决策模型,它将游戏AI的行为分解为一系列的决策节点,并通过节点之间的连接关系来描述游戏AI的行为逻辑。在行为决策树中,每个节点都代表一个行为或决策,例如移动、攻击、逃跑等…...
Spring学习记录
目录 bean的单例与多例 设置 工厂模式的三种形态 简单工厂模式 代码: 运行结果: 总结: 工厂模式 代码: 运行结果: 总结: 抽象工厂模式 代码: 运行结果: 总结: …...
模板方法-
定义:又叫模板模式,是指定义一个算法骨架,并允许子类为其中的一个或多个步骤提供实现。 适用场景: 1、一次性实现一个算法不变的部分,并将可变的行为留给子类来实现 2、各子类中公共的行为被提取出来并集中到一个公共的父类中,从而避免代码重复 优点…...
[Kubernetes] - RabbitMQ学习
1.消息队列 消息: 在应用间传送的数据队列,先进先出 1.2. 作用 好处:解耦, 容错,削峰坏处:降低系统可用性,系统复杂度提高,一致性问题; RabbitMQ组成部分:…...
swagger页面 doc.html出不来,swagger-ui/index.html能出来
swagger页面 doc.html出不来,swagger-ui/index.html能出来。前前后后折腾了很久,jar包冲突,jar包版本,添加路径啥的都弄了,就是出不来。 后来全局搜索“doc.html”页面发现能出来的项目能搜到这个页面: 定…...
IEEE802.3和IEEE802.11的分类(仅为分类)
IEEE802.3标准 IEEE802.3:10兆以太网 ●10Base-5 使用粗同轴电缆,最大网段长度为500m,基带传输方法; ●10Base-2 使用细同轴电缆,最大网段长度为185m,基带传输方法; ●10Base&am…...
c# cad二次开发通过获取excel数据 在CAD绘图,将CAD属性导出到excel
c# cad二次开发通过获取excel数据 在CAD绘图,将CAD属性导出到excel using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Runtime; using System; using System.Collections.Generic; using System.Linq; us…...
LLM之高性能向量检索库
LLM向量数据库 高性能向量检索库milvus简介安装调用 faiss简介安装调用 高性能向量检索库 milvus 简介 Milvus 是一个开源的向量数据库引擎,旨在提供高效的向量存储、检索和分析能力。它被设计用于处理大规模的高维向量数据,常用于机器学习、计算机视觉…...
实体类注解
目录 一、TableField注解 二、TableId注解 三、Table注解 四、TableLogic注解 五、Getter与Setter注解 六、EqualsAndHashCode注解 七、Accessors注解 一、TableField注解 Data NoArgsConstructor //空参构造方法 AllArgsConstructor //全参构造方法 TableName("t…...
常见数据结构种类
常见数据结构种类 数据存储的常用结构有:栈、队列、数组、链表和红黑树 a.队列(queue) – 先进先出,后进后出。 – 场景:各种排队。叫号系统。 – 有很多集合可以实现队列。 b.栈(stack) – …...
linux高级---k8s中的五种控制器
文章目录 一、k8s的控制器类型二、pod与控制器之间的关系三、状态与无状态化对特点四、Deployment1、Deployment的资源清单文件2、在配置清单中调用deployment控制器3、镜像更新4、金丝雀发布5、删除Deployment 五、Statefulset六、DaemonSet1、daemonset的资源清单文件2、在配…...
记一次udp服务性能优化经历
目录 概述磁盘io网络io减少重复计算减少内存复制减少互斥锁 概述 手上有个go项目,接收udp信息(主要是syslog和snmp trap)并查询设备信息,将信息结构化(设备ip名称,匹配了什么规则之类的)后发送…...
uniapp和VueI18n多语言H5项目语言国际化功能搭建流程
uniapp多语言项目国家化功能搭建流程 说明:uniapp多语言项目功能搭建分为应用部分和框架部分。 应用部分,即开发者自己的代码里涉及的界面部分的语言翻译。框架部分,即uni-app内置组件和API涉及界面的部分的语言翻译。 功能的搭建是需要un…...
C# | 凸包算法之Jarvis,寻找一组点的边界/轮廓
C#实现凸包算法之Jarvis 文章目录 C#实现凸包算法之Jarvis前言示例代码实现思路测试结果结束语 前言 这篇关于凸包算法的文章,本文使用C#和Jarvis算法来实现凸包算法。 首先消除两个最基本的问题: 什么是凸包呢? 凸包是一个包围一组点的凸多…...
SpringBoot接收请求参数的方式
【方式一】原始方式 因为SpringBoot封装了Servlet,所以也允许使用HttpServletRequest类中的方法来获取 /*** 【方式一】原始方式*/RequestMapping("/demo01")public String demo01(HttpServletRequest request) {// 参数名要与页面提交的参数名一致Strin…...
MKS SERVO4257D 闭环步进电机_系列5 CAN指令说明
第1部分 产品介绍 MKS SERVO 28D/35D/42D/57D 系列闭环步进电机是创客基地为满足市场需求而自主研发的一款产品。具备脉冲接口和RS485/CAN串行接口,支持MODBUS-RTU通讯协议,内置高效FOC矢量算法,采用高精度编码器,通过位置反馈&am…...
Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
Java毕业设计:WML信息查询与后端信息发布系统开发
JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发,实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构,服务器端使用Java Servlet处理请求,数据库采用MySQL存储信息࿰…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...
相关类相关的可视化图像总结
目录 一、散点图 二、气泡图 三、相关图 四、热力图 五、二维密度图 六、多模态二维密度图 七、雷达图 八、桑基图 九、总结 一、散点图 特点 通过点的位置展示两个连续变量之间的关系,可直观判断线性相关、非线性相关或无相关关系,点的分布密…...
JS红宝书笔记 - 3.3 变量
要定义变量,可以使用var操作符,后跟变量名 ES实现变量初始化,因此可以同时定义变量并设置它的值 使用var操作符定义的变量会成为包含它的函数的局部变量。 在函数内定义变量时省略var操作符,可以创建一个全局变量 如果需要定义…...
