python使用 flask+vue 制作前后端分离图书信息管理系统
哈喽兄弟们,今天咱们来用Python实现一个前后端分离的图书信息管理系统。
1、前端部分
首先,我们可以使用 VueJS 作为前端框架,并通过 Vue CLI 工具进行创建和管理项目。
2、后端部分
后端部分我们可以采用 Python Flask 框架,这个框架是一个轻量级的Web框架,十分适合快速开发API接口。
3、前端和后端交互
前后端的交互可以采用 Restful API 设计的方式进行,例如创建一个图书列表接口,前端只需要发送一个 GET 请求给后端,后端通过查询数据库,返回 JSON 格式的数据给前端。
4、数据库
为了方便管理图书信息,我们可以使用关系型数据库 MySQL 存储和管理相关数据。
5、部署
可以使用 Docker 将前后端应用部署在同一个容器内,或者使用 CI/CD 工具将前后端应用分别部署在不同的服务器上。
总的来说,通过使用以上技术栈,我们就可以实现一个前后端分离的图书信息管理系统。
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/
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' 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': '数据添加成功' } 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> <!-- 数据表格 --> <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"> 完整源码文档:加V:python1018 备注【LL】快速通过领取 <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:python1018 备注【LL】快速通过领取 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(() => { }); }
好了,今天的分享就差不多到这里了!
对下一篇大家想看什么,可在评论区留言,看到我会更新的。
喜欢就关注一下博主,或点赞收藏评论一下我的文章吧!!!