1. 项目背景与核心需求
药品仓库管理是医疗机构运营中至关重要的环节。传统的手工记录方式效率低下且容易出错,而市面上的通用仓库管理系统往往无法满足诊所特有的药品管理需求。这正是我们选择用Python开发轻量级药品仓库管理系统的原因。
Flask和Django作为Python两大主流Web框架各有优势:Flask轻量灵活适合快速开发小型应用,Django则提供"开箱即用"的全套解决方案。在诊所场景下,我们需要在系统轻量化和功能完整性之间找到平衡点。
2. 技术选型分析
2.1 Flask vs Django框架对比
Flask的优势在于:
- 微内核设计,核心功能精简
- 扩展机制灵活,可按需添加功能
- 学习曲线平缓,适合小型项目快速开发
Django的强项包括:
- 自带ORM、Admin等完整组件
- 内置用户认证、权限管理等企业级功能
- 遵循"约定优于配置"原则
经过实际测试,我们发现:
对于药品库存量在500种以下的小型诊所,Flask的性能表现更优;而当药品品类超过1000种时,Django的ORM效率优势开始显现。
2.2 混合架构设计
最终我们采用混合架构:
- 核心业务逻辑使用Flask实现
- 数据管理后台采用Django Admin
- 通过REST API进行数据交互
这种设计既保证了前端的灵活性,又利用了Django强大的后台管理能力。具体技术栈如下:
| 组件 | 技术选型 | 备注 |
|---|---|---|
| Web框架 | Flask 2.3 + Django 4.2 | 主业务用Flask,后台用Django |
| 数据库 | PostgreSQL 14 | 支持事务和复杂查询 |
| ORM | SQLAlchemy + Django ORM | 混合使用 |
| 前端 | Bootstrap 5 + Vue.js | 响应式设计 |
3. 核心功能实现
3.1 药品信息管理模块
药品数据模型设计是关键。我们采用以下字段结构:
class Medicine(db.Model): __tablename__ = 'medicines' id = db.Column(db.Integer, primary_key=True) code = db.Column(db.String(20), unique=True) # 药品编码 name = db.Column(db.String(100)) # 通用名称 spec = db.Column(db.String(50)) # 规格 unit = db.Column(db.String(10)) # 单位 stock = db.Column(db.Integer) # 当前库存 min_stock = db.Column(db.Integer) # 最低库存预警 price = db.Column(db.Float) # 单价 batch = db.Column(db.String(30)) # 批次号 expiry_date = db.Column(db.Date) # 有效期实现药品CRUD操作时需要注意:
- 批次管理必须记录完整流转信息
- 效期管理需要每日自动扫描临近过期药品
- 库存变动必须记录操作日志
3.2 库存预警系统
我们开发了多级预警机制:
- 库存下限预警(黄色)
- 缺货预警(红色)
- 近效期预警(蓝色)
预警逻辑实现代码示例:
def check_stock_warnings(): # 获取所有库存低于最小库存的药品 low_stock = Medicine.query.filter( Medicine.stock < Medicine.min_stock ).all() # 获取30天内过期的药品 nearing_expiry = Medicine.query.filter( Medicine.expiry_date <= datetime.now() + timedelta(days=30) ).all() return { 'low_stock': low_stock, 'nearing_expiry': nearing_expiry }3.3 采购管理流程
药品采购流程包括:
- 生成采购计划(基于库存预警)
- 创建采购订单
- 到货验收
- 入库登记
我们使用状态机模式管理采购流程:
class PurchaseOrder: STATES = ['draft', 'confirmed', 'delivered', 'checked', 'completed'] def __init__(self): self.state = 'draft' def confirm(self): if self.state == 'draft': self.state = 'confirmed' def deliver(self): if self.state == 'confirmed': self.state = 'delivered' # 其他状态转换方法...4. 系统部署方案
4.1 开发环境配置
推荐使用虚拟环境隔离项目依赖:
# 创建虚拟环境 python -m venv venv # 激活环境 source venv/bin/activate # Linux/Mac venv\Scripts\activate # Windows # 安装依赖 pip install flask django psycopg2-binary4.2 生产环境部署
我们采用Nginx + Gunicorn方案:
- Nginx作为反向代理和静态文件服务器
- Gunicorn作为WSGI应用服务器
- Supervisor管理进程
典型Nginx配置:
server { listen 80; server_name clinic.example.com; location / { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location /static/ { alias /path/to/static/files; } }启动Gunicorn:
gunicorn -w 4 -b 127.0.0.1:8000 app:app5. 实际应用中的经验总结
5.1 性能优化技巧
数据库查询优化:
- 使用SQLAlchemy的lazy loading避免N+1查询问题
- 对高频查询添加适当索引
- 批量操作代替循环单条处理
缓存策略:
- 药品基础信息使用Redis缓存
- 库存数据实时性要求高,不缓存
前端优化:
- 使用Vue.js实现数据绑定
- 分页加载大数据量列表
5.2 常见问题排查
药品编码冲突:
- 实现自动查重功能
- 采用"类别码+序列号"的复合编码规则
库存不一致:
- 所有库存变动必须通过统一接口
- 实现定期库存校对功能
效期管理遗漏:
- 设置每日自动扫描任务
- 重要预警需要多种通知方式(站内+邮件+短信)
5.3 安全注意事项
权限控制:
- 不同角色区分操作权限
- 敏感操作需要二次确认
数据备份:
- 每日全量备份+binlog增量备份
- 备份文件加密存储
审计日志:
- 记录所有关键操作
- 日志不可篡改
6. 扩展与演进
系统后续可以扩展的方向:
- 与HIS系统对接
- 移动端应用开发
- 加入药品图片识别功能
- 实现供应商门户
在开发过程中,我们深刻体会到:药品管理系统不同于普通仓库管理,必须特别关注批次追踪、效期管理和药品特性等专业需求。Flask+Django的混合架构在保持灵活性的同时,也让我们能够快速实现业务需求。