PYTHON制作前后端分离的图书信息管理系统(flask+vue)

news2025/4/18 5:28:13

前言

嗨喽,大家好呀~这里是爱看美女的茜茜呐

本次案例,使用 flask、vue、elements-plus、axios

制作一个基于 restful api 的前后端分离的图书信息管理案例

效果展示


👇 👇 👇 更多精彩机密、教程,尽在下方,赶紧点击了解吧~

素材、视频教程、完整代码、插件安装教程我都准备好了,直接在文末名片自取就可


后端部分

flask: https://flask.palletsprojects.com/en/2.1.x/

flask-sqlalchemy: https://flask-sqlalchemy.palletsprojects.com/en/2.x/

flask-cors: https://flask-cors.readthedocs.io/en/latest/

flask 快速上手

from flask import Flask, request
app = Flask(__name__)
@app.route('/')
def hello_world(): # put application's code here
return 'Welcome Books!'

数据库部分

# -*- coding: utf-8 -*-
from extension import db
class Book(db.Model):
__tablename__ = 'book'
#完整源码文档:加V:pytho8987免费获取
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
book_number = db.Column(db.String(255), nullable=False)
book_name = db.Column(db.String(255), nullable=False)
book_type = db.Column(db.String(255), nullable=False)
book_prize = db.Column(db.Float, nullable=False)
author = db.Column(db.String(255))
book_publisher = db.Column(db.String(255))
@staticmethod
def init_db():
rets = [
(1, '001', '活着', '小说', 39.9, '余华', '某某出版社'),
(2, '002', '三体', '科幻', 99.8, '刘慈欣', '重庆出版社')
]
for ret in rets:
book = Book()
book.id = ret[0]
book.book_number = ret[1]
book.book_name = ret[2]
book.book_type = ret[3]
book.book_prize = ret[4]
book.author = ret[5]
book.book_publisher = ret[6]
db.session.add(book)
db.session.commit()

使用之前需要 flask create 初始化一下数据

接口部分

RESTful API 最佳实践(阮一峰) : https://www.ruanyifeng.com/blog/2018/10/restful-api-best-practice
s.html

Method Views for APIs: https://flask.palletsprojects.com/en/2.1.x/views/#method-views-for-apis

from flask import Flask, request
from flask_cors import CORS
from flask.views import MethodView
from extension import db
from models import Book
app = Flask(__name__)
CORS().init_app(app)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///books.sqlite'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db.init_app(app)
@app.cli.command()
def create():
db.drop_all()
db.create_all()
Book.init_db()
@app.route('/')
def hello_world(): # put application's code here
return 'Welcome Books!'
class BookApi(MethodView):
def get(self, book_id):
if not book_id:
books: [Book] = Book.query.all()
results = [
{
'id': book.id,
'book_name': book.book_name,
'book_type': book.book_type,
'book_prize': book.book_prize,
'book_number': book.book_number,
'book_publisher': book.book_publisher,
'author': book.author,
} for book in books
]
return {
'status': 'success',
'message': '数据查询成功',
'results': results
}
book: Book = Book.query.get(book_id)
return {
'status': 'success',
'message': '数据查询成功',
'result': {
'id': book.id,
'book_name': book.book_name,
'book_type': book.book_type,
'book_prize': book.book_prize,
'book_number': book.book_number,
'book_publisher': book.book_publisher,
'author': book.author,
}
}
def post(self):
form = request.json
book = Book()
book.book_number = form.get('book_number')
book.book_name = form.get('book_name')
book.book_type = form.get('book_type')
book.book_prize = form.get('book_prize')
book.author = form.get('author')
book.book_publisher = form.get('book_publisher')
db.session.add(book)
db.session.commit()
# id, book_number, book_name, book_type, book_prize, author,
book_publisher
return {
'status': 'success',
'message': '数据添加成功'
}
完整源码文档:加V:pytho8987免费获取
def delete(self, book_id):
book = Book.query.get(book_id)
db.session.delete(book)
db.session.commit()
return {
'status': 'success',
'message': '数据删除成功'
}
def put(self, book_id):
book: Book = Book.query.get(book_id)
book.book_type = request.json.get('book_type')
book.book_name = request.json.get('book_name')
book.book_prize = request.json.get('book_prize')
book.book_number = request.json.get('book_number')
book.book_publisher = request.json.get('book_type')
book.author = request.json.get('book_type')
db.session.commit()
return {
'status': 'success',
'message': '数据修改成功'
}
book_api = BookApi.as_view('book_api')
app.add_url_rule('/books', view_func=book_api, methods=['GET', ], defaults=
{'book_id': None})
app.add_url_rule('/books', view_func=book_api, methods=['POST', ])
app.add_url_rule('/books/<int:book_id>', view_func=book_api, methods=['GET',
'PUT', 'DELETE'])

前端部分

vite: https://vitejs.cn/

vue3: https://v3.cn.vuejs.org/

Element Plus: https://element-plus.gitee.io/zh-CN/

axios: https://axios-http.com/docs/intro

项目创建

C:\Users\xxp\Desktop>npm init vite@latest
 Project name: ... book-fontend
 Select a framework: » vue
 Select a variant: » vue
Scaffolding project in C:\Users\xxp\Desktop\book-fontend...
Done. Now run:
cd book-fontend
npm install
npm run dev

项目初始化

npm install element-plus
npm install axios

初始化 element-plus

import {createApp} from 'vue'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
const app = createApp(App)
app.use(ElementPlus)
app.mount('#app')

页面创建

表单数据显示

<template>
<div style="margin: 0 auto;width: 50%;">
<h1 style="text-align: center">图书管理系统</h1>
<!-- 添加图书按钮 -->
<el-button type="primary" @click="add_dialog_visible = true" size="small">
加图书</el-button>
<!-- 数据表格 -->
完整源码文档:加V:pytho8987免费获取
<el-table :data="books" style="margin: 20px auto;">
<el-table-column label="编号" prop="book_number"/>
<el-table-column label="书名" prop="book_name"/>
<el-table-column label="类型" prop="book_type"/>
<el-table-column label="价格" prop="book_prize"/>
<el-table-column label="作者" prop="author"/>
<el-table-column label="出版社" prop="book_publisher"/>
<el-table-column align="right" label="操作" width="200px">
<template #default="scope">
<el-button size="small" @click="handleEdit(scope.$index, scope.row)">
编辑
</el-button>
<el-button
size="small"
type="danger"
@click="handleDelete(scope.$index, scope.row)"
>
删除
</el-button
>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script setup>
import axios from 'axios'
import {reactive, ref, onMounted} from "vue";
import {ElMessageBox} from 'element-plus'
const books = reactive([])
const getStudents = () => {
axios.get("http://localhost:5000/books",).then(res => {
books.splice(0, books.length)
books.push(...res.data.results)
console.log('更新数据')
})
}
// 页面渲染之后添加数据
onMounted(() => {
getStudents()
})
// 删除数据
const handleDelete = (index, scope) => {
axios.delete(`http://localhost:5000/books/${scope.id}`).then(() => {
getStudents()
})
}
</script>

添加数据

html表单

<!-- 添加图书页面 -->
<el-dialog
title="添加图书"
v-model="add_dialog_visible"
width="30%"
:before-close="handleClose"
>
<el-form
ref="ruleFormRef"
:model="book_form"
status-icon
label-width="120px"
class="demo-ruleForm"
>
<el-form-item label="编号" prop="book_number">
<el-input v-model="book_form.book_number" autocomplete="off"/>
</el-form-item>
<el-form-item label="书名" prop="book_name">
<el-input v-model="book_form.book_name" autocomplete="off"/>
</el-form-item>
<el-form-item label="类型" prop="book_type">
<el-input v-model="book_form.book_type" autocomplete="off"/>
</el-form-item>
<el-form-item label="价格" prop="book_prize">
<el-input v-model.number="book_form.book_prize" autocomplete="off"/>
</el-form-item>
<el-form-item label="作者" prop="author">
<el-input v-model="book_form.author" autocomplete="off"/>
</el-form-item>
<el-form-item label="出版社" prop="book_publisher">
<el-input v-model="book_form.book_publisher" autocomplete="off"/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm(ruleFormRef)">提交</elbutton>
<el-button @click="resetForm(ruleFormRef)">重置</el-button>
</el-form-item>
</el-form>
</el-dialog>

JavaScript

/*表单添加*/
const add_dialog_visible = ref(false)
const ruleFormRef = ref()
const book_form = reactive({
book_number: "",
book_name: "",
book_type: "",
book_prize: "",
author: "",
book_publisher: "",
id: "",
})
// 表单提交事件
const submitForm = (formEl) => {
完整源码文档:加V:pytho8987免费获取
axios.post('http://localhost:5000/books', book_form).then(() => {
add_dialog_visible.value = false
formEl.resetFields()
getStudents()
})
}
// 重置表单
const resetForm = (formEl) => {
formEl.resetFields()
}
// 关闭弹窗前确认
const handleClose = (done) => {
ElMessageBox.confirm('确认关闭?')
.then(() => {
done();
})
.catch(() => {
});
}

尾语

感谢你观看我的文章呐~本次航班到这里就结束啦 🛬

希望本篇文章有对你带来帮助 🎉,有学习到一点知识~

躲起来的星星🍥也在努力发光,你也要努力加油(让我们一起努力叭)。

最后,宣传一下呀~👇👇👇更多源码、资料、素材、解答、交流皆点击下方名片获取呀👇👇

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/568649.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python 的 type 函数和 isinstance 函数

type()、isinstance()都是对象类型操作函数&#xff0c;用于判定对象类型&#xff0c;用哪个函数更好哩&#xff1f; 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free&#xff1a;大咖免费“圣经”教程《 python 完全自学教程》&#xff0c;…

数字档案馆建设指南

数字档案馆建设指南 目 录 1.总体要求 2.管理系统功能要求 3.应用系统开发和服务平台构建 4.数字档案资源建设 5.保障体系建设 1.总体要求 1.1概述 数字档案馆是指各级各类档案馆为适应信息社会日益增长的对档案信息资源管理、利用需求&#xff0c;运用现代信息技术对数字…

一只羊的奥秘,您可知羊是有四个胃的噢

很多人知道反刍动物&#xff0c;但是对于反刍动物的四个胃怎样消化&#xff0c;不太了解&#xff0c;今天小编就介绍一下&#xff0c;反刍动物为何需要四个胃消化食物。 反刍俗称倒嚼&#xff0c;是指某些动物进食经过一段时间以后将半消化的食物从胃里返回嘴里再次咀嚼。反刍主…

有效项目进度管理的 10 条规则

项目进度管理是项目中比较关键的方面之一&#xff0c;因为它将决定事情的进展方式、进展速度以及是否会取得进展。换句话说&#xff0c;它可以让你较好地控制项目&#xff0c;帮助你预测不可预测的情况&#xff0c;并使所有相关团队能够高效地协同工作。 以下是有效项目进度管…

如何在华为OD机试中获得满分?Java实现【寻找两个正序数组的中位数】一文详解!

✅创作者&#xff1a;陈书予 &#x1f389;个人主页&#xff1a;陈书予的个人主页 &#x1f341;陈书予的个人社区&#xff0c;欢迎你的加入: 陈书予的社区 &#x1f31f;专栏地址: Java华为OD机试真题&#xff08;2022&2023) 文章目录 1. 题目描述2. 输入描述3. 输出描述…

3.数据结构期末复习之栈和队列

1.栈的应用 1.括号匹配问题(还有确定他们的符号优先级) 如 2((32) * 3) /3 扫描到左括号入栈,右括号入另外一个栈,如果两个栈数量相同,则是匹配的,不保存,不然去找最少的栈,出来提示报错2.十进制转2进制 如 23转二进制10111&#xff0c;需要栈辅助 每次除2的余数倒过来写3.mai…

Vue3(一):创建vue3工程、setup、vue3响应式原理、computed和watch

Vue3&#xff1a;第一章 一、创建Vue3.0工程1.使用vue-cli创建2.使用vite创建 二、Vue3中的响应式1.拉开序幕的setup2.ref函数3.reactive函数4.vue3中响应式的原理&#xff08;1&#xff09;vue2中响应式原理&#xff08;2&#xff09;Vue3中的Proxy 5.reactive和ref的对比6.se…

性能测试如何做?超详细性能测试-测试策略总结,新人进阶之路...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 性能测试出现的初…

YOLOv5【训练train.py逐行源码及参数调参解析】超详细解读!!!建议收藏✨✨!

之前的文章介绍了YOLOv5的网络结构&#x1f680;与目录结构源码&#x1f680;以及detect.py&#x1f680;的详细解读&#xff0c;今天带来的是YOLOv5的 train.py 代码参数逐行解读以及注释&#xff0c;废话不多说&#xff0c;让我们一起学习YOLOv5的 train.py 源码吧&#xff0…

功能测试和自动化测试的差距在哪里?

一直以来&#xff0c;软件的测试主要是以手工测试为主&#xff0c;但是随着现代软件的复杂程度的加深&#xff0c;人们对使用手工方式来完成软件测试感到的越来越力不从心&#xff0c;同时因为在软件测试中存在着大量的重复性工作&#xff0c;而这种工作是比较适合机器而不是人…

rsync

配置rsync源服务器&#xff1a; #建立/etc/rsyncd.conf 配置文件 vim /etc/rsyncd.conf #添加以下配置项 uid root gid root use chroot yes #禁锢在源目录 address 192.168.80.10 …

​Kali-linux无线网络嗅探工具Kismet​

如果要进行无线网络渗透测试&#xff0c;则必须先扫描所有有效的无线接入点。刚好在Kali Linux中&#xff0c;提供了一款嗅探无线网络工具Kismet。使用该工具可以测量周围的无线信号&#xff0c;并查看所有可用的无线接入点。本节将介绍使用Kismet工具嗅探无线网络。 &#xf…

MySQL_6 自连接和外连接

目录 一、自连接 1.概述 : 2.语法 : 3.演示 : 二、外连接 1.为什么需要外连接&#xff1f; 2.外连接的定义 : 3.外连接的演示 : 1 左外连接 2 右外连接 3 对部门表问题的解决 一、自连接 1.概述 : 自连接是指在同一张表上的连接查询&#xff08;将同一张看做两张表)&a…

R语言实践——rWCVP:按照物种的原生分布区清洗坐标点

rWCVP&#xff1a;按照物种的原生分布区清洗坐标点 加载库工作流&#xff08;单个物种&#xff09;1. 下载发现记录数据&#xff08;rgbif&#xff09;2. 发现记录的预备3. 获取原生区范围4. 清除非原生分布记录 加载库 library(rWCVP) library(rgbif) library(tidyverse) lib…

产品Backlog和需求管理

产品Backlog 产品backlog是一个按照价值排序的需求清单。为了达成产品目标&#xff0c;所有的需求都需要放到产品backlog中进行管理和规划。由产品负责人负责管理和维护。Leangoo为每一个里程碑建立了一个产品Backlog看板, 通过这个产品backlog看板来进行需求管理和规划。 里…

搭建服务器的主流中间件有哪些?如何在外网访问内网的服务?

计算机业内人士对于搭建服务器的中间件并不陌生&#xff0c;apache、tomcat、IIS、nginx 都是比较常用的搭建服务器的中间件&#xff0c;它们之间还是有一些区别差异的。今天就说说这些中间件之间有哪些区别&#xff0c;以及如何利用快解析实现内网主机应用让外网访问。 首先说…

大数据入门(六)- UCloud创建云服务器

一.注册UCloud账户 使用UCloud的服务&#xff0c;首先需要注册账户 账户注册非常简单&#xff0c;在UCloud网站首页&#xff08;https://www.ucloud.cn/&#xff09;右上角点击快速注册 二.创建VPC 1.注册成功后&#xff0c;选择全部产品 2.选择私有网络UVPC 3.区域选择华北…

uni-app开发小程序使用uni.chooseMedia选择图片,安卓手机无法选择图片

uni-app开发小程序时&#xff0c;使用uni.chooseMedia选择图片&#xff0c;苹果手机是正常的&#xff0c;安卓手机无法打开手机选择图片 问题复现解决方法&#xff01;&#xff01;我的反思与总结 问题复现 一、在小程序中&#xff0c;选择图片并上传&#xff0c;是一个很常见…

[Python报错] ImportError: cannot import name ‘timer’ from ‘timer’

[Python报错] ImportError: cannot import name ‘timer’ from ‘timer’ 前言 我最近遇到这个报错&#xff0c;卡了我好长时间去解决&#xff0c;我在互联网上找了很多资料&#xff0c;遗憾的是&#xff0c;我没找到有其他人遇到的类似的问题。所以在这里做一下记录。事实上…

两年外包,从4K涨到了15K....

我18年毕业于一个普通二本学校&#xff0c;电子信息工程学院&#xff0c;是一个很不出名的小本科。大学期间专业知识也没有去认真的学习&#xff0c;所以毕业的时候就随便找了一份工作&#xff0c;在一个外包公司做功能测试。 记得那时候薪资大概是4k左右&#xff0c;因为是以…