Python簡易圖書管理系統重構

在本篇課文中,我們將使用Python語言結合MySQL數據庫,從零開始構建一個簡單的圖書管理系統。該系統旨在幫助圖書館管理員輕松管理圖書的借閱、歸還以及查詢圖書信息等日常操作。我們將分步介紹需求分析、數據庫設計、環境搭建、功能實現等關鍵環節,并提供詳細的源代碼示例。

#### **一、需求分析**

圖書管理系統的核心功能包括:
- 圖書錄入:允許管理員添加新書到系統。
- 圖書查詢:提供按書名、作者、ISBN等關鍵詞查詢圖書。
- 借閱管理:記錄借閱者信息及圖書借閱狀態。
- 歸還管理:更新圖書狀態為可借閱。
- 數據統計:統計各類圖書的借閱次數等。

#### **二、數據庫設計**

首先,我們需要設計兩個基本表:`books` 和 `borrow_records`。

1. **books** 表結構示例:
?

?- `id` INT PRIMARY KEY AUTO_INCREMENT,- `title` VARCHAR(255) NOT NULL,- `author` VARCHAR(100),- `isbn` VARCHAR(13) UNIQUE,- `status` ENUM('available', 'borrowed') DEFAULT 'available'

2. **borrow_records** 表結構示例:
?

 ?- `id` INT PRIMARY KEY AUTO_INCREMENT,- `book_id` INT,- `borrower_name` VARCHAR(100),- `borrow_date` DATE,- `return_date` DATE DEFAULT NULL,- FOREIGN KEY (`book_id`) REFERENCES `books`(`id`)

當然,以下是之前設計的圖書管理系統中涉及到的MySQL數據庫表創建語句。這些語句會創建`users`(用戶)、`books`(圖書)和`borrow_records`(借閱記錄)三個表。請根據實際情況調整數據庫用戶名、密碼以及數據庫名稱。

```sql


-- 創建 users 表,用于存儲系統用戶信息
CREATE TABLE IF NOT EXISTS `users` (`id` INT AUTO_INCREMENT PRIMARY KEY,`username` VARCHAR(64) NOT NULL UNIQUE,`password` VARCHAR(128) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;-- 注意:在實際應用中,應該使用哈希函數處理密碼,不要明文存儲
-- 示例:`password`字段的值應該是 `hash_function('your-clear-text-password')`-- 創建 books 表,存儲圖書信息
CREATE TABLE IF NOT EXISTS `books` (`id` INT AUTO_INCREMENT PRIMARY KEY,`title` VARCHAR(255) NOT NULL,`author` VARCHAR(100),`isbn` VARCHAR(13) UNIQUE NOT NULL,`status` ENUM('available', 'borrowed') DEFAULT 'available'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;-- 創建 borrow_records 表,記錄圖書的借閱情況
CREATE TABLE IF NOT EXISTS `borrow_records` (`id` INT AUTO_INCREMENT PRIMARY KEY,`book_id` INT,`borrower_name` VARCHAR(100) NOT NULL,`borrow_date` DATE NOT NULL,`return_date` DATE DEFAULT NULL,FOREIGN KEY (`book_id`) REFERENCES `books`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;-- 確保外鍵約束在刪除書籍記錄時級聯刪除借閱記錄

```

請確保在執行這些SQL語句前,你的MySQL服務器已經啟動并且你有合適的權限來創建數據庫和表。如果使用的是圖形化界面的數據庫管理工具(如phpMyAdmin或MySQL Workbench),可以直接在對應的界面輸入這些SQL命令來創建表。

#### **三、環境搭建**

確保安裝了Python和MySQL,以及必要的庫:
- 安裝`mysql-connector-python`用于Python連接MySQL。
- 安裝`prettytable`用于美化輸出。

```bash

pip install mysql-connector-python prettytable


```

#### **四、功能實現**

接下來,我們逐步實現上述功能。

##### 1. 連接數據庫```python

import mysql.connector
from prettytable import PrettyTabledef create_conn():conn = mysql.connector.connect(host='localhost',user='your_username',password='your_password',database='library_db')return conndef close_conn(conn):if conn.is_connected():conn.close()


```

##### 2. 圖書錄入

```python

def add_book(title, author, isbn):conn = create_conn()cursor = conn.cursor()query = "INSERT INTO books (title, author, isbn) VALUES (%s, %s, %s)"try:cursor.execute(query, (title, author, isbn))conn.commit()print("圖書添加成功!")except mysql.connector.Error as err:print(f"錯誤:{err}")finally:close_conn(conn)


```

##### 3. 圖書查詢

```python

def search_books(keyword):conn = create_conn()cursor = conn.cursor()query = "SELECT * FROM books WHERE title LIKE %s OR author LIKE %s"pattern = f"%{keyword}%"cursor.execute(query, (pattern, pattern))rows = cursor.fetchall()if rows:table = PrettyTable(["ID", "書名", "作者", "ISBN", "狀態"])for row in rows:table.add_row(row)print(table)else:print("未找到相關圖書。")close_conn(conn)


```

##### 4. 借閱圖書

```python

def borrow_book(book_id, borrower_name):conn = create_conn()cursor = conn.cursor()# 檢查圖書是否可借check_query = "SELECT status FROM books WHERE id = %s AND status = 'available'"cursor.execute(check_query, (book_id,))result = cursor.fetchone()if result:update_query = "UPDATE books SET status = 'borrowed' WHERE id = %s"insert_query = "INSERT INTO borrow_records (book_id, borrower_name, borrow_date) VALUES (%s, %s, CURDATE())"cursor.execute(update_query, (book_id,))cursor.execute(insert_query, (book_id, borrower_name))conn.commit()print("圖書借閱成功!")else:print("該圖書不可借閱。")close_conn(conn)


```

##### 5. 歸還圖書

```python

def return_book(book_id):conn = create_conn()cursor = conn.cursor()# 更新圖書狀態update_query = "UPDATE books SET status = 'available' WHERE id = %s"cursor.execute(update_query, (book_id,))# 更新歸還日期update_return_date = "UPDATE borrow_records SET return_date = CURDATE() WHERE book_id = %s AND return_date IS NULL"cursor.execute(update_return_date, (book_id,))conn.commit()if cursor.rowcount > 0:print("圖書歸還成功!")else:print("該圖書未借出或已歸還。")close_conn(conn)


```

#### **五、運行示例**

在實際使用中,可以根據需要調用上述函數來完成相應的圖書管理任務。例如,要添加一本新書,可以這樣操作:

```python

add_book("Python編程入門", "John Doe", "978-3-16-148410-0")


```

通過以上步驟,我們已經構建了一個基本的圖書管理系統。當然,實際應用中還需要考慮更多細節,比如異常處理、用戶界面、權限管理等,但本教程為你提供了實現此類系統的基本框架和思路。希望這個示例能激發你進一步探索Python與數據庫應用開發的興趣。

頁面展示:

### **環境準備**

確保已安裝以下依賴:
- Flask
- Flask-Login(用于權限管理)
- Flask-WTF(表單處理)
- Flask-SQLAlchemy(簡化SQLAlchemy與Flask的集成)
- Bootstrap(前端樣式框架)

```bash

pip install flask flask-login flask-wtf flask-sqlalchemy


```

### **項目結構**

```plaintext
book_management/

├── app.py
├── templates/
│ ? ├── base.html
│ ? ├── login.html
│ ? ├── dashboard.html
│ ? └── ...
├── static/
│ ? ├── css/
│ ? │ ? └── style.css
│ ? └── js/
│ ? ? ? └── script.js
├── models.py
└── forms.py
```

### **核心代碼示例**

#### **app.py** - 應用入口```python

from flask import Flask, render_template, redirect, url_for
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user
from models import db, User, Books, BorrowRecords, login
from forms import LoginForm, AddBookFormapp = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key'
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://username:password@localhost/library_db'
db.init_app(app)
login.init_app(app)
login.login_view = 'login'@app.route('/')
@login_required
def dashboard():form = AddBookForm()books = Books.query.all()return render_template('dashboard.html', books=books, form=form)@app.route('/login', methods=['GET', 'POST'])
def login():form = LoginForm()if form.validate_on_submit():user = User.query.filter_by(username=form.username.data).first()if user and user.password == form.password.data:login_user(user)return redirect(url_for('dashboard'))else:form.password.errors.append('Invalid username or password.')return render_template('login.html', form=form)@app.route('/logout')
@login_required
def logout():logout_user()return redirect(url_for('login'))@app.route('/add_book', methods=['POST'])
@login_required
def add_book():form = AddBookForm()if form.validate_on_submit():new_book = Books(title=form.title.data, author=form.author.data, isbn=form.isbn.data)db.session.add(new_book)db.session.commit()return redirect(url_for('dashboard'))return redirect(url_for('dashboard'))if __name__ == '__main__':app.run(debug=True)


```

#### **models.py** - 數據模型定義```python

from flask_sqlalchemy import SQLAlchemy
from werkzeug.security import generate_password_hash, check_password_hashdb = SQLAlchemy()class User(UserMixin, db.Model):id = db.Column(db.Integer, primary_key=True)username = db.Column(db.String(64), unique=True, nullable=False)password = db.Column(db.String(128), nullable=False)class Books(db.Model):id = db.Column(db.Integer, primary_key=True)title = db.Column(db.String(255), nullable=False)author = db.Column(db.String(100))isbn = db.Column(db.String(13), unique=True, nullable=False)status = db.Column(db.Enum('available', 'borrowed'), default='available')# 注意:省略了BorrowRecords模型以簡化示例


```

#### **forms.py** - 表單定義```python

from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Length, ValidationErrorclass LoginForm(FlaskForm):username = StringField('Username', validators=[DataRequired()])password = PasswordField('Password', validators=[DataRequired()])submit = SubmitField('Log In')class AddBookForm(FlaskForm):title = StringField('Title', validators=[DataRequired()])author = StringField('Author')isbn = StringField('ISBN', validators=[DataRequired(), Length(min=13, max=13)])submit = SubmitField('Add Book')


```

#### **前端模板** - 使用Bootstrap美化

在`templates/dashboard.html`中,你可以使用Bootstrap框架來美化你的網頁布局和樣式。例如,為圖書列表添加表格樣式,以及使用Bootstrap表單組件來美化添加圖書的表單。

當然,下面是一個簡化的`templates/dashboard.html`示例,展示了如何使用Bootstrap來美化圖書管理系統的前端界面。此模板包括一個登錄后的儀表板頁面,其中包含圖書列表和一個添加新書的表單。```html
<!doctype html>
<html lang="en">
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}"><link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous"><title>圖書管理系統</title>
</head>
<body><nav class="navbar navbar-expand-lg navbar-light bg-light"><a class="navbar-brand" href="#">圖書管理系統</a><button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav"aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"><span class="navbar-toggler-icon"></span></button><div class="collapse navbar-collapse" id="navbarNav"><ul class="navbar-nav ml-auto"><li class="nav-item"><a class="nav-link" href="{{ url_for('logout') }}">登出</a></li></ul></div>
</nav><div class="container mt-3"><h2>圖書列表</h2><table class="table table-striped"><thead><tr><th scope="col">#</th><th scope="col">書名</th><th scope="col">作者</th><th scope="col">ISBN</th><th scope="col">狀態</th></tr></thead><tbody>{% for book in books %}<tr><td>{{ book.id }}</td><td>{{ book.title }}</td><td>{{ book.author }}</td><td>{{ book.isbn }}</td><td>{{ book.status }}</td></tr>{% endfor %}</tbody></table><h2>添加新書</h2><form method="post" action="{{ url_for('add_book') }}" class="mt-4">{{ form.hidden_tag() }}<div class="form-group">{{ form.title.label(class="form-control-label") }}{{ form.title(class="form-control") }}</div><div class="form-group">{{ form.author.label(class="form-control-label") }}{{ form.author(class="form-control") }}</div><div class="form-group">{{ form.isbn.label(class="form-control-label") }}{{ form.isbn(class="form-control") }}</div><button type="submit" class="btn btn-primary">添加圖書</button></form>
</div><script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js"integrity="sha384-IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p"crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV"crossorigin="anonymous"></script>
</body>
</html>
```

此模板利用了Bootstrap的CSS和JS文件,以及jQuery和Popper.js(Bootstrap的一些JavaScript插件依賴它們)。請注意,你需要確保在你的`static/css`目錄下有一個`style.css`文件,用于存放自定義的CSS樣式。此外,Flask的`url_for`函數被用來正確地鏈接靜態資源和路由。

### **總結**

通過上述重構,我們的圖書管理系統不僅增加了異常處理和用戶界面,還引入了基本的權限管理機制,并通過Bootstrap對網頁進行了美化。這使得系統更加易用且具有一定的安全防護能力,適合小型圖書館或個人項目使用。請記得根據實際情況調整數據庫配置、密鑰等敏感信息,并根據需要進一步完善功能和優化前端設計。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/13285.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/13285.shtml
英文地址,請注明出處:http://en.pswp.cn/web/13285.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

注冊講堂 | 體外診斷試劑分類目錄的變化

5月11日&#xff0c;千呼萬喚的《體外診斷試劑分類目錄》&#xff08;2024年第58號&#xff09;終于發布&#xff01; 前世今生 2013年&#xff1a;《6840 體外診斷試劑分類子目錄&#xff08;2013版&#xff09;》&#xff08;以下簡稱2013版目錄&#xff09; 2017年&#xff…

蘋果永久版安裝PD虛擬機:Parallels Desktop 19 一鍵激活版

Parallels Desktop 19是一款功能強大的虛擬機軟件&#xff0c;專為Mac用戶設計&#xff0c;允許用戶在同一臺Mac電腦上同時運行Windows、Linux等多個操作系統&#xff0c;而無需額外的硬件設備。 下載地址&#xff1a;https://www.macz.com/mac/9581.html?idOTI2NjQ5Jl8mMjcuM…

Kubernetes入門:核心概念

集群架構與組件 一個kubernetes集群主要是由控制節點(master)、工作節點(node)構成&#xff0c;每個節點上都會安裝不同的組件。 master&#xff1a;集群的控制平面&#xff0c;負責集群的決策 ( 管理 ) api-server : 資源操作的唯一入口&#xff0c;接收用戶輸入的命令&…

vue3 項目中 前端實現下載模板 csv文件

做項目時遇到讓前端實現模板下載功能&#xff0c;第一次碰到這種需求&#xff0c;記錄一下。 下載csv 模板&#xff1a; <el-button type"primary" click"download(data/CSVXX.csv)">下載模板</el-button> const download (url) > {con…

文本控件Text Control示例: 將圖像插入 TX 的各種方法

TX Text Control 是一款功能類似于 MS Word 的文字處理控件&#xff0c;包括文檔創建、編輯、打印、郵件合并、格式轉換、拆分合并、導入導出、批量生成等功能。廣泛應用于企業文檔管理&#xff0c;網站內容發布&#xff0c;電子病歷中病案模板創建、病歷書寫、修改歷史、連續打…

在Linux上面部署ELK

注明&#xff1a;一下的軟件需要自己準備 一、準備環境&#xff1a; 1.兩臺elasticsearch主機4G內存 2.兩臺elasticsearch配置主機名node1和node2(可以省略) #vim /etc/hostname #reboot 3. 兩臺elasticsearch配置hosts文件 #vim /etc/hosts 192.168.1.1 node1 192…

RTMP低延遲推流

人總是需要壓力才能進步, 最近有個項目, 需要我在RK3568上, 推流到公網, 最大程度的降低延遲. 廢話不多說, 先直接看效果: 數據經過WiFi發送到Inenter的SRS服務器, 再通過網頁拉流的. 因為是打金任務, 所以逼了自己一把, 把RTMP推流好好捋一遍. 先說說任務目標, 首先是MPP編碼…

【Altium】AD-檢查原理圖中元器件未連接的Passive Pin

1、 文檔目標 如何讓原理圖編譯時找出元器件上未連接的Passive Pin 2、 問題場景 當引腳屬性&#xff08;Pin type&#xff09;為passive時&#xff0c;原理圖編譯的默認規則是不會去檢查它們是否有連接的。在實際設計過程中&#xff0c;經常會有導線虛連&#xff0c;漏連的事…

醫療傳感器種類不斷增多 市場規模逐漸擴大

醫療傳感器種類不斷增多 市場規模逐漸擴大 醫療傳感器是將人體的生理信息轉換為電信息的變換裝置。醫療傳感器具有高靈敏度、高精度、實時監測等優點&#xff0c;可以檢測佩戴者的心率、呼吸頻率、活動量等&#xff0c;從而更加準確地了解身體情況。   經過多年發展&#…

【極簡】docker常用操作

鏡像images是靜態的 容器container是動態的&#xff0c;是基于鏡像的&#xff0c;類似于一個進程。 查看docker images&#xff1a; docker images 或者docker image ls 查看docker container情況&#xff1a;docker ps -a&#xff0c;-a意思是--all 運行一個container: doc…

MySQL not in不等于找不到null的數據

在使用MySQL的NOT IN語句時&#xff0c;如果找不到NULL值&#xff0c;可能是因為NULL值在比較中具有特殊性質。NULL值不等于任何其他值&#xff0c;包括它自己。因此&#xff0c;使用NOT IN語句時&#xff0c;如果列表中包含NULL值&#xff0c;則查詢不會返回任何結果。 解決此…

有意思的數組

var nums [1,2,3,6] const nums1 [6, 8, 7, 10, 9];/* 數組合并————push */ var n nums.push(...nums1); // 將列表 nums1 拼接到 nums 之后 n //n會是nums的長度 > 9 nums //也push了 > (9) [1, 2, 3, 6, 6, 8, 7, 10, 9]/* 數組合并————concat*/ var arr0…

數字水印 | 奇異值分解 SVD 的 Python 代碼實現

&#x1f951;原理&#xff1a;數字水印 | 奇異值分解 SVD 的定義、原理及性質 &#x1f951;參考&#xff1a;Python 機器學習筆記&#xff1a;奇異值分解&#xff08;SVD&#xff09;算法 正文 對于一個圖像矩陣&#xff0c;我們總可以將其分解為以下形式&#xff1a; 通過…

使用API有效率地管理Dynadot域名,默認將域名隱形轉發至其他界面

關于Dynadot Dynadot是通過ICANN認證的域名注冊商&#xff0c;自2002年成立以來&#xff0c;服務于全球108個國家和地區的客戶&#xff0c;為數以萬計的客戶提供簡潔&#xff0c;優惠&#xff0c;安全的域名注冊以及管理服務。 Dynadot平臺操作教程索引&#xff08;包括域名郵…

英譯漢早操練-(十九)

hello,are you OK? 生活如此美好&#xff0c;周四了&#xff0c;你還好嗎&#xff1f;堅持了快一周了&#xff0c;是不是最后沖刺一把就開啟周末的美好生活了。 今天我們學習這篇經濟學人文章&#xff1a; 題目是&#xff1a;Banks, at least, are making money from a turbul…

【大模型微調】一文掌握7種大模型微調的方法

本篇文章深入分析了大型模型微調的基本理念和多樣化技術&#xff0c;細致介紹了LoRA、適配器調整(Adapter Tuning)、前綴調整(Prefix Tuning)等多個微調方法。詳細討論了每一種策略的基本原則、主要優點以及適宜應用場景&#xff0c;使得讀者可以依據特定的應用要求和計算資源限…

Linux | VMware安裝鏡像指南(Windows、IOS、麒麟)

文章目錄 虛擬機安裝推薦 虛擬機安裝推薦 macOS系統&#xff1a;macOS虛擬機安裝全過程&#xff08;VMware&#xff09;麒麟系統&#xff1a;麒麟系統虛擬機安裝&#xff08;VMware&#xff09;VMtools工具解決方案&#xff1a; [第一步](https://blog.csdn.net/weixin_421187…

openGauss一主兩備集群異常斷電后不能正常啟動的解決過程簡記

背景 因異常斷電后opengauss 5.0.0版本&#xff0c;一主兩備集群啟動失敗。 報錯不是主機&#xff0c;由于當時沒有截圖&#xff0c;查看日志后發現報錯是&#xff1a; 定位過程 Day1 1. 嘗試用另外兩臺機器啟動每臺機器 發現都報錯自己不是主機&#xff0c;像極了唐僧被妖…

【算法刷題day55】Leetcode:583. 兩個字符串的刪除操作、72. 編輯距離

文章目錄 Leetcode 583. 兩個字符串的刪除操作解題思路代碼總結 Leetcode 72. 編輯距離解題思路代碼總結 草稿圖網站 java的Deque Leetcode 583. 兩個字符串的刪除操作 題目&#xff1a;583. 兩個字符串的刪除操作 解析&#xff1a;代碼隨想錄解析 解題思路 dp數組的含義是&a…