十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Python药店药品管理系统源码:毕业设计课程设计实战指南

Python药店药品管理系统源码:毕业设计课程设计实战指南 简介这份资源是面向计算机相关专业学生与Python初学者的药店药品管理系统完整项目包可直接用于毕业设计、课程设计或自学练手。系统围绕药品库存管理、销售记录、采购计划与库存预警等日常业务展开帮助读者理解如何将数据库设计、前后端交互与界面开发整合为可运行的实际应用。压缩包共392个文件约20.63MB以jpeg、svg、jpg、png等图片资源为主配合36个py源码文件、35个ts与16个vue前端组件、9个js脚本及json、md等配置说明整体呈现前后端分离的工程结构便于按模块阅读与二次开发。目前已有120人学习下载。项目涵盖数据模型、视图与控制器分层、依赖清单及使用说明读者可据此掌握面向对象建模、数据库操作、GUI或Web界面搭建与异常处理等技能并借鉴其目录组织与代码规范快速形成自己的设计文档与答辩材料。1. 从一份药店药品管理系统源码说起它到底能帮你交掉哪门课毕业设计选题季后台被问得最多的一类问题是有没有那种能跑起来、能改、能写进论文的 Python 项目。药店药品管理系统就是被翻牌率极高的一类——它不像推荐系统那样玄学也不像深度学习那样吃显卡本质是一套带业务规则的增删改查加库存预警用 Python 加一个关系型数据库就能闭环。对计算机毕业设计、软件工程课程设计、数据库课程设计这三类任务来说它几乎是万金油业务实体清晰药品、供应商、库存、销售、用户表关系能画出漂亮的 ER 图功能点够写三四十页答辩时老师问的每一个问题你都能落到具体代码上。这份「基于 python 的药店药品管理系统」压缩包通常包含源码、数据库脚本和一份说明文档。它解决的不是「从零发明一个系统」而是「在有限时间里交出一个结构完整、逻辑自洽、能演示的成品」。适合谁正在赶毕业设计、课程设计 deadline 的本科生尤其是基础一般、不想碰硬件对比基于 stm32 的毕业设计那种要焊板子的方向的同学。下面我按真实落地顺序把环境、建库、核心模块、避坑、进阶一条条拆开讲。2. 环境与选型为什么药店系统用 Python MySQL 而不是别的2.1 技术栈怎么定Flask、Tkinter 还是 Django拿到源码第一件事不是急着运行而是判断它属于哪一类界面形态这决定了你后面怎么改、怎么截图写论文。药店药品管理系统常见的三种实现路线差别很大路线界面形态适合场景上手难度Tkinter 桌面版本地窗口程序课程设计、单机演示低Flask 网页浏览器访问毕业设计、要写 Web 章节中Django 全栈浏览器 自带后台想省事、要 Admin 管理中高我一般建议如果论文里要写「B/S 架构」「前后端交互」选 Flask如果只是课程设计交个能跑的作业Tkinter 最省心不用配服务器。Django 自带 admin 后台药品表建好后几乎不用写管理界面但它的 ORM 和目录结构对新手不友好改起来容易迷路。选 Python 而不是 Java 的理由很实在语法短、依赖装得快、数据库驱动成熟。热搜里 java 课程设计案例源码 一大堆但 Java 的 Maven 依赖和 Tomcat 配置对赶 deadline 的人是额外负担。Python 这边pip install一行就完事出问题也好搜。2.2 环境搭建python 安装到 vscode 配置的完整链路环境是翻车重灾区。很多人卡在 python 安装、python 下载安装教程这一步装完发现命令行里python不认。按下面顺序走第一步装 Python。去官网下 3.8 到 3.11 之间的版本别追最新。安装时务必勾选「Add Python to PATH」这一步漏了后面全是坑。# 验证安装是否成功两条命令都试 python --version pip --version # 如果 python 不认试 python3 python3 --version第二步配编辑器。vscode python 环境配置 的核心是选对解释器按CtrlShiftP输入Python: Select Interpreter选中你刚装的那个。选错了会出现「明明装了库却提示 ModuleNotFoundError」。第三步建虚拟环境。这是后悔药能避免不同项目的库版本打架# 在项目根目录执行 python -m venv venv # Windows 激活 venv\Scripts\activate # macOS / Linux 激活 source venv/bin/activate # 激活后命令行前面会出现 (venv)第四步装依赖。看源码根目录有没有requirements.txtpip install -r requirements.txt # 如果没有这个文件常见依赖手动装 pip install flask pymysql openpyxlflask是 Web 框架pymysql是 MySQL 驱动注意不是mysqlclient后者在 Windows 上编译经常失败openpyxl用于导出 Excel 报表。参数说明如果源码用的是mysql-connector-python就把pymysql换掉别两个都装容易在连接时冲突。提示虚拟环境激活后再装库否则库会装到全局换项目时版本冲突会让你怀疑人生。2.3 数据库选型MySQL 建库脚本怎么读药店系统的数据关系是典型的「多表关联」药品属于某个分类销售记录关联药品和用户库存变动关联入库单。用 MySQL 是数据库课程设计 mysql 方向的标准答案。源码里一般有个.sql文件先别急着导入打开看三样东西字符集、引擎、外键。-- 建库时指定字符集避免中文乱码 CREATE DATABASE pharmacy DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE pharmacy; -- 药品表注意主键自增和库存字段的默认值 CREATE TABLE medicine ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(100) NOT NULL COMMENT 药品名称, category_id INT COMMENT 分类ID, price DECIMAL(10,2) DEFAULT 0.00 COMMENT 售价, stock INT DEFAULT 0 COMMENT 库存数量, warn_stock INT DEFAULT 10 COMMENT 预警阈值, expiry_date DATE COMMENT 有效期 ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;逻辑说明utf8mb4而不是utf8因为后者存不了 emoji 和部分生僻字药品名里偶尔有特殊字符会报错。InnoDB引擎支持事务和外键销售扣库存时必须用事务否则并发下会超卖。DECIMAL(10,2)存价格绝不能用FLOAT浮点数算钱会出现0.10.20.30000000000000004这种事故。导入命令mysql -u root -p pharmacy pharmacy.sql参数说明-u后跟用户名-p回车后输密码是重定向导入。如果报Unknown database说明库还没建先执行建库语句。3. 核心模块落地登录、药品管理、库存预警怎么写3.1 数据库连接封装一个文件管住所有 SQL新手最容易犯的错是把数据库连接写死在每个函数里改个密码要翻十几个文件。正确做法是抽一个db.pyimport pymysql def get_conn(): 统一获取数据库连接改配置只改这里 return pymysql.connect( hostlocalhost, # 数据库地址 port3306, # 默认端口 userroot, # 用户名 password123456, # 改成你自己的密码 databasepharmacy, # 库名 charsetutf8mb4, # 必须和建库一致 cursorclasspymysql.cursors.DictCursor # 返回字典方便取值 ) def query(sql, argsNone): 查询返回列表 conn get_conn() try: with conn.cursor() as cur: cur.execute(sql, args) return cur.fetchall() finally: conn.close() def execute(sql, argsNone): 增删改返回影响行数 conn get_conn() try: with conn.cursor() as cur: rows cur.execute(sql, args) conn.commit() # 必须提交否则数据不落库 return rows except Exception as e: conn.rollback() # 出错回滚保证一致性 raise e finally: conn.close()逻辑说明DictCursor让查询结果变成{name: 阿莫西林}这种字典比元组下标好读得多。execute里commit和rollback成对出现这是事务的基本功答辩时老师很爱问。参数说明args用参数化传值比如query(SELECT * FROM medicine WHERE name%s, (name,))绝不能用字符串拼接否则就是 SQL 注入的活教材。3.2 药品增删改查把 CRUD 写成能演示的功能药品管理是系统的主干。以 Flask 为例一个查询接口长这样from flask import Flask, request, jsonify from db import query, execute app Flask(__name__) app.route(/medicine/list) def medicine_list(): 支持按名称模糊搜索分页返回 keyword request.args.get(keyword, ) page int(request.args.get(page, 1)) size int(request.args.get(size, 10)) offset (page - 1) * size sql SELECT m.*, c.name AS category_name FROM medicine m LEFT JOIN category c ON m.category_id c.id WHERE m.name LIKE %s ORDER BY m.id DESC LIMIT %s OFFSET %s data query(sql, (f%{keyword}%, size, offset)) return jsonify({code: 0, data: data})逻辑说明LEFT JOIN把分类名一起查出来前端不用再发一次请求。LIKE %s配合f%{keyword}%实现模糊搜索注意%是拼在参数值里而不是 SQL 里这样仍然走参数化。LIMIT ... OFFSET是分页标准写法page从 1 开始offset是跳过的行数。新增药品要校验必填项和价格合法性app.route(/medicine/add, methods[POST]) def medicine_add(): d request.json # 后端必须再校验一次前端校验能被绕过 if not d.get(name) or float(d.get(price, 0)) 0: return jsonify({code: 1, msg: 名称或价格不合法}) sql INSERT INTO medicine(name, category_id, price, stock, warn_stock, expiry_date) VALUES(%s, %s, %s, %s, %s, %s) execute(sql, (d[name], d[category_id], d[price], d[stock], d.get(warn_stock, 10), d.get(expiry_date))) return jsonify({code: 0, msg: 添加成功})参数说明warn_stock给默认值 10前端不传也不会报错。expiry_date允许为空因为不是所有药品都强制录有效期。这里的关键是后端二次校验——很多同学只在前端用 JavaScript 校验答辩时被问「绕过前端直接发请求怎么办」就答不上来。3.3 库存预警与销售扣减事务是这里的命门库存预警的逻辑是查询stock warn_stock的药品前端标红。真正难的是销售扣库存必须用事务锁住行def sell(medicine_id, quantity): 销售扣库存事务保证不超卖 conn get_conn() try: with conn.cursor() as cur: # FOR UPDATE 锁行防止并发下两个请求同时读到相同库存 cur.execute(SELECT stock FROM medicine WHERE id%s FOR UPDATE, (medicine_id,)) row cur.fetchone() if not row or row[stock] quantity: conn.rollback() return False, 库存不足 cur.execute(UPDATE medicine SET stock stock - %s WHERE id%s, (quantity, medicine_id)) cur.execute(INSERT INTO sale(medicine_id, quantity, sale_time) VALUES(%s, %s, NOW()), (medicine_id, quantity)) conn.commit() return True, 销售成功 except Exception as e: conn.rollback() return False, str(e) finally: conn.close()逻辑说明FOR UPDATE是行级锁把这条药品记录锁住另一个并发请求会等待读到的就是扣减后的库存从根本上杜绝超卖。扣库存和写销售记录在同一个事务里要么都成功要么都回滚。参数说明quantity必须为正整数调用前校验NOW()是 MySQL 函数写入当前时间。注意FOR UPDATE必须在事务里才生效如果 autocommit 开着锁会立刻释放等于没加。4. 避坑与排查跑不起来时先看这几条4.1 中文乱码从建库到连接的三处字符集现象药品名显示成????或å½é¿è¥¿æ。原因字符集在三个地方可能不一致——建库时、建表时、连接时。解决建库用utf8mb4建表继承库设置连接串里显式写charsetutf8mb4。三处对齐后重启程序。如果已经建了表用ALTER TABLE medicine CONVERT TO CHARACTER SET utf8mb4;补救。4.2 ModuleNotFoundError装了库却提示找不到现象pip install flask成功运行却报No module named flask。原因pip 装到了全局环境而 vscode 用的是虚拟环境解释器两者不是同一个 Python。解决先激活虚拟环境再装库然后在 vscode 里重新Select Interpreter指向venv里的 python。用which pythonWindows 用where python确认当前用的是哪个。4.3 数据库连接报 1045 或 2003现象Access denied for user或Cant connect to MySQL server。原因1045 是密码错或用户没权限2003 是 MySQL 服务没启动或端口不对。解决1045 检查db.py里的密码确认 MySQL 用户能从 localhost 登录2003 先确认 MySQL 服务在运行Windows 服务管理器里看或net start mysql再确认端口是 3306 没被改。4.4 外键约束导致删不掉数据现象删除某个药品分类时报Cannot delete or update a parent row。原因该分类下还有药品外键约束阻止删除。解决要么先删或转移该分类下的药品要么在建表时把外键设为ON DELETE SET NULL。我一般建议保留约束删除前先查一下关联数据给用户明确提示这比直接放开约束更安全。4.5 端口被占用Flask 启动报 Address already in use现象OSError: [Errno 98] Address already in use。原因5000 端口被别的程序占了或者上一个 Flask 进程没退干净。解决换端口app.run(port5001)或者找到占用进程杀掉。Windows 用netstat -ano | findstr 5000查 PID再taskkill /PID xxx /F。5. 进阶技巧把系统改出论文亮点而不是只交个 CRUD5.1 加一个数据可视化看板论文立刻有内容可写纯 CRUD 的药店系统在答辩时容易被说「工作量不够」。加一个销售统计看板用 ECharts 或 Pyecharts 画图论文里就能多出「数据可视化」一章。后端提供一个统计接口app.route(/stats/sale_trend) def sale_trend(): 近 7 天销售趋势按天聚合 sql SELECT DATE(sale_time) AS day, SUM(quantity) AS total FROM sale WHERE sale_time DATE_SUB(CURDATE(), INTERVAL 7 DAY) GROUP BY DATE(sale_time) ORDER BY day return jsonify({code: 0, data: query(sql)})逻辑说明DATE_SUB(CURDATE(), INTERVAL 7 DAY)算出 7 天前的日期GROUP BY DATE(sale_time)按天分组求和。参数说明INTERVAL 7 DAY里的 7 可以改成 30 做月度报表。前端拿到day和total两个数组直接喂给图表库。5.2 用触发器或定时任务处理药品过期药品有效期是药店系统的特色功能。两种做法一是查询时动态判断expiry_date CURDATE()标记为过期二是写个定时任务每天扫描。动态判断简单但数据量大时每次查询都要算。我一般用动态判断加索引-- 给有效期加索引加速过期查询 CREATE INDEX idx_expiry ON medicine(expiry_date); -- 查询 30 天内即将过期的药品 SELECT name, expiry_date FROM medicine WHERE expiry_date BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 30 DAY);参数说明BETWEEN ... AND ...包含边界DATE_ADD算未来日期。加索引后即使几万条数据过期查询也是毫秒级。5.3 导出 Excel答辩演示的加分项老师看到能一键导出报表印象分直接上去。用openpyxl实现from openpyxl import Workbook from flask import send_file import io app.route(/export/medicine) def export_medicine(): wb Workbook() ws wb.active ws.title 药品清单 ws.append([ID, 名称, 价格, 库存, 有效期]) # 表头 for m in query(SELECT * FROM medicine): ws.append([m[id], m[name], float(m[price]), m[stock], str(m[expiry_date] or )]) buf io.BytesIO() wb.save(buf) buf.seek(0) return send_file(buf, as_attachmentTrue, download_namemedicine.xlsx, mimetypeapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheet)逻辑说明io.BytesIO在内存里生成文件不用落盘适合 Web 场景。send_file的as_attachmentTrue让浏览器弹下载框。参数说明download_name是下载的文件名mimetype必须写对否则浏览器可能直接打开而不是下载。注意expiry_date可能是None用or 兜底否则str(None)会写入字符串None。5.4 我踩过的那些坑说个血泪经验我第一次做这类系统时把数据库密码硬编码在五个文件里换台电脑演示时全崩现场改代码改到冒汗。后来养成习惯配置统一放一个config.py用环境变量读取源码里只留占位符。还有一次销售扣库存没用事务演示时手快点了两下库存直接变成负数老师当场问「并发怎么办」我只能尴尬地说「演示环境不考虑」。这些坑现在看都是基本功但赶 deadline 的时候真的会忽略。另一个习惯是每改完一个模块就git commit一次别等全写完再提交。答辩前一晚改崩了还能回滚这是真正的后悔药。数据库脚本也单独存一份别和源码混在一起导入导出都清爽。这套药店药品管理系统看着简单但把事务、索引、参数化查询、前后端校验这些点吃透你收获的不只是一份能交的作业而是一套能复用到其他管理系统的方法论。希望帮到你。本文还有配套的精品资源点击获取
返回列表