news 2026/10/23 11:03:28

Django+MySQL街区医院管理系统:毕业设计源码拆解与实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Django+MySQL街区医院管理系统:毕业设计源码拆解与实战

简介:基于Python的街区医院管理系统的设计与实现毕业设计资料包(含论文与源码),面向高校计算机相关专业学生,尤其是需要完成医院管理类课设或毕设的开发者。资料围绕Python、Django、MySQL及B/S架构展开,从选题背景、研究意义、需求分析、性能与可行性分析,到总体架构、数据库设计、功能模块实现和系统测试,完整呈现了一个Web管理系统的开发闭环。论文部分包含登录流程图、添加用户流程图、数据库E/R图、核心数据表设计、测试用例以及管理员/医生/患者模块的实现说明;源码阶段则可直接运行或二次开发,方便对照论文验证系统行为。压缩包整体34.66MB,文件总数与类型明细暂未提供,下载后可查看内部内容。目前已有56人浏览/学习,整体内容按毕业设计标准整理,既能作为课程设计模板,也可为后续功能扩展提供基础。

1. 毕业设计选型先看这里:Python + Django + MySQL 这套门诊系统值不值得拆

又到毕业设计和课程设计扎堆的时间,很多同学拿到手的题目不是“太难”而是“太虚”,论文东拼西凑,代码跑不起来。这份街区医院管理系统,用的就是 Python 3 + Django + MySQL 这套最主流的 B/S 技术栈,论文和源码打包成一个压缩包。它能解决三件事:论文里需求分析、数据库设计、系统测试怎么落地;源码里管理员、医生、患者三个角色怎么分工;以及你拿到手之后怎么快速跑起来、哪些参数要改。适合正在找 Python 毕业设计参考、想完整复现一个管理系统的开发者,也适合想把 Django 从“会写小 Demo”推进到“能拆一个完整项目”的初学者。下面按我拆源码的习惯,从技术选型讲到数据库建模,再讲到功能实现和常见翻车点,最后补一份测试用例和交付检查清单。

2. 技术选型与项目骨架:为什么偏偏是 Django + MySQL + B/S

2.1 三个技术选型的答辩理由

先回答最常被导师追问的问题:为什么用 Django 不用 Flask,为什么配 MySQL 不用 SQLite。Django 自带 ORM、Admin 后台、用户认证三大件,对一个“管理员 + 医生 + 患者”三类角色的管理系统来说,等于把地基打好了。Flask 灵活但很多模块要自己拼,课程设计和本科毕设的时间通常不允许你从零搭权限和会话。MySQL 则是因为它和 Django ORM 配合成熟,网上排错资料多,而且管理系统最终要面对多人并发访问,SQLite 在并发写场景下容易锁库。

B/S 架构是这个项目的默认答案:浏览器端零安装,医院里不管是用 Windows 电脑还是平板,打开浏览器就能访问。相比 C/S 结构,不用给每台机器装客户端,升级时只需要改服务器。答辩时可以强调“部署成本低、维护集中”,这正好对应论文里“运行可行性”和“操作可行性”两节。

2.2 环境准备:虚拟环境与依赖安装

拿到源码包第一步,别急着点运行,先建虚拟环境把依赖锁住。常见做法是用 venv 创建隔离环境,然后通过 requirements.txt 一次性装完。Django 项目依赖装错版本是毕设跑不起来的头号原因,尤其是 Django 和 mysqlclient 的版本匹配问题。

# 1. 创建虚拟环境,python -m 指定解释器版本 python -m venv venv # 2. 激活环境,Windows 与 macOS/Linux 命令不同 # Windows: venv\Scripts\activate source venv/bin/activate # macOS / Linux # 3. 安装依赖,建议用清华或阿里镜像加速 pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple

这里venv的作用是把项目依赖和系统 Python 环境隔离,避免不同项目之间版本冲突。requirements.txt 里通常锁定了 Django、mysqlclient、pillow 等核心包,如果源码包没带这个文件,可以手动补一个:Django 版本建议 4.x 或 3.2 LTS,mysqlclient 装与系统匹配的最新版。装完依赖后跑python manage.py migrate初始化数据库表,再python manage.py runserver启动开发服务器。

2.3 项目骨架:从源码包目录看 Django 标准分层

拆开源码包,一个规范的 Django 项目通常是这样的目录结构。看清这个结构,后面改代码才知道去哪找:

hospital_manage/ ├── manage.py # 项目管理入口,常用命令都走这里 ├── requirements.txt # 依赖清单 ├── db.sqlite3 / 数据库配置 # 实际项目用 MySQL,需要改 settings ├── hospital/ # 主应用目录(名称可能不同) │ ├── settings.py # 全局配置:数据库、静态文件、应用注册 │ ├── urls.py # 根路由 │ ├── __init__.py ├── app_admin/ # 管理员模块 │ ├── models.py # 数据模型 │ ├── views.py # 视图函数 │ ├── urls.py # 模块内路由 ├── app_doctor/ # 医生模块 │ ├── models.py │ ├── views.py ├── app_patient/ # 患者模块 │ ├── models.py │ ├── views.py ├── templates/ # HTML 模板 └── static/ # 静态文件:CSS/JS/图片

拿到源码先打开settings.py,重点看三处:INSTALLED_APPS里是否注册了每个子应用,DATABASES里的连接配置是否指向你的 MySQL,TIME_ZONE和USE_TZ是否会导致时间差 8 小时。我习惯把数据库配置单独提到一段,方便维护:

# settings.py 中数据库配置示例 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'hospital_db', # 数据库名,先创建好 'USER': 'root', # 数据库账号 'PASSWORD': 'your_password', # 改成你自己的密码 'HOST': '127.0.0.1', # 本地开发 'PORT': '3306', 'OPTIONS': { 'charset': 'utf8mb4', # 关键:避免中文乱码 'init_command': 'SET sql_mode=\'STRICT_TRANS_TABLES\'', }, } }

这里的ENGINE必须是django.db.backends.mysql而不是 sqlite3,NAME对应的数据库要在 MySQL 里提前建好,否则 migrate 时直接报“Unknown database”。OPTIONS里的charset我建议固定写 utf8mb4,它能存下中文和常用表情符号,老项目用 utf8 在特殊字符上会栽跟头。改完配置先跑一句python manage.py check,能看到配置层面的报错。

3. 需求分析与数据库设计:从 E/R 图到五张核心表的落地

3.1 功能需求分析:三类角色的用例边界

论文第 3 章的需求分析决定了代码的模块划分。这个系统的角色很典型:管理员、医生、患者。管理员负责用户管理、医生信息维护和基础数据配置;医生负责查看排班、接诊患者、书写病历、开处方;患者负责注册登录、挂号、查询病历和检查结果。三者的权限必须隔离,这也是 Django 自带auth应用能直接覆盖的部分。

画用例图时建议把“登录”抽成公共用例,把“挂号”放在患者侧,把“写病历”放在医生侧。这里有个容易混淆的地方:挂号记录到底算患者的还是医生的?我一般这样处理:挂号记录表存患者 ID、医生 ID、就诊时间和状态,它属于患者模块的入口,但医生端同样要能查到当天挂了自己的患者列表,所以字段设计要双向可查。

3.2 数据库设计:从 E/R 图到落地表格

论文里画了数据库 E/R 图,落地成表其实就五张核心表。设计原则就是三范式:不搞重复字段、外键指向明确、单表语义纯净。下面的字段清单可以直接对到 models.py:

表名核心字段说明
用户表id, username, password, role, real_name, phone复用 Django 内置 User 表或自定义扩展
医生信息表id, user_id, department, title, introduction, schedule与用户表一对一
患者信息表id, user_id, gender, age, medical_history, allergy与用户表一对一
排班表id, doctor_id, work_date, time_slot, remaining医生排班、号源控制
挂号记录表id, patient_id, doctor_id, visit_date, status, diagnosis核心业务表,状态标记已完成/待就诊

3.3 models.py 核心建模与参数说明

实际项目里很多源码没有拆这么细,而是用一对多或多对多直接解决。比如排班表和挂号记录表,推荐的建模方式如下:

# app_doctor/models.py from django.db import models from django.contrib.auth.models import User class DoctorProfile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE, verbose_name='关联用户') department = models.CharField(max_length=50, verbose_name='科室') title = models.CharField(max_length=20, verbose_name='职称') introduction = models.TextField(blank=True, verbose_name='简介') def __str__(self): return f"{self.user.username} - {self.department}" class Schedule(models.Model): doctor = models.ForeignKey(DoctorProfile, on_delete=models.CASCADE, verbose_name='医生') work_date = models.DateField(verbose_name='出诊日期') time_slot = models.CharField(max_length=20, verbose_name='时段', choices=[ ('morning', '上午'), ('afternoon', '下午')]) remaining = models.PositiveIntegerField(default=20, verbose_name='剩余号源') class Meta: unique_together = ('doctor', 'work_date', 'time_slot') verbose_name = '排班'
# app_patient/models.py class Appointment(models.Model): patient = models.ForeignKey(PatientProfile, on_delete=models.CASCADE, verbose_name='患者') schedule = models.ForeignKey(Schedule, on_delete=models.CASCADE, verbose_name='排班') visit_date = models.DateField(verbose_name='就诊日期') status = models.CharField(max_length=10, default='pending', verbose_name='状态', choices=[ ('pending', '待就诊'), ('done', '已完成'), ('cancelled', '已取消')]) diagnosis = models.TextField(blank=True, verbose_name='诊断结果') created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')

OneToOneField保证一个登录账号只对应一条医生或患者资料,ForeignKey表示一对多。unique_together是排班表的关键约束:同一个医生同一天同一时段只能有一条排班记录,这能在数据库层面防重复。PositiveIntegerField用来存号源剩余数,并可以配合视图层做挂号时的防超卖。choices参数让状态字段在 Admin 后台变成下拉框,避免手输脏数据。

需要注意,Django 自带的User表字段固定,建议扩展Profile表而不是直接改它,否则后续升级 Django 版本容易出问题。源码包里的模型可能命名不同,但结构大差不差,拿到手先对照表清单核对一遍。

4. 核心功能实现:注册登录到三类角色的最小可用闭环

4.1 注册登录:用 Django auth 应用做会话控制

Django 的auth应用把注册、登录、注销的底层逻辑都写好了,重点是写清视图逻辑和路由配置。很多毕设源码在这里把核心逻辑塞进一个视图里,如果拆开看,其实就是复用authenticate和login两个函数。

# app_patient/views.py 中登录视图 from django.shortcuts import render, redirect from django.contrib.auth import authenticate, login from django.contrib.auth.models import User def login_view(request): if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') # 调用 Django 认证逻辑,校验用户名和密码 user = authenticate(request, username=username, password=password) if user is not None: login(request, user) # 写入 session,后续请求免登录 return redirect('/index/') else: # 用户名或密码错误,回到登录页并给出提示 return render(request, 'login.html', {'error': '用户名或密码错误'}) return render(request, 'login.html')

authenticate只负责校验账号密码,不产生会话;login才会把用户 ID 写进 session 并下发 sessionid cookie。这个区分是答辩常考点。注册视图则需要先查重再创建用户:

def register_view(request): if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') password2 = request.POST.get('password2') if User.objects.filter(username=username).exists(): return render(request, 'register.html', {'error': '用户名已存在'}) if password != password2: return render(request, 'register.html', {'error': '两次密码不一致'}) # create_user 会自动对密码做哈希,不要用 create user = User.objects.create_user(username=username, password=password) return redirect('/login/') return render(request, 'register.html')

注释里特别强调create_user而不是create:前者会对密码做 PBKDF2 哈希再入库,后者会把明文密码直接存进去,这在答辩演示时一旦被看到就是大扣分项。

4.2 管理员模块:用户管理与权限隔离

管理员端的核心操作是查看用户列表、新增用户、停用账号。视图层一般用@login_required加@user_passes_test两层保护。下面是一个典型的用户列表视图:

# app_admin/views.py from django.contrib.auth.decorators import login_required, user_passes_test from django.contrib.auth.models import User def is_admin(user): # 通过扩展表或 User 字段判断角色 return user.is_staff @login_required # 未登录用户跳转到登录页 @user_passes_test(is_admin) # 非管理员直接拒绝 def user_list(request): users = User.objects.all().order_by('-date_joined') return render(request, 'admin/user_list.html', {'users': users})

is_staff是 Django 内置的管理员标记,毕设中也可以自定义一个角色字段。order_by('-date_joined')让新注册用户排在最前面,方便管理员审核。这里要注意:只加@login_required会导致普通患者也能访问管理员页面,必须配合角色判断。

4.3 医生与患者功能:从写病历到挂号流程

医生端的核心场景是查看当天排班、选择待就诊患者、填写诊断结果。患者端的核心场景是选择科室和医生、确认时段、生成挂号记录。两个模块通过Appointment表衔接。下面给出医生完成接诊的视图:

# app_doctor/views.py from django.shortcuts import get_object_or_404 from app_patient.models import Appointment def finish_visit(request, appointment_id): # 只有医生本人能操作,取当前登录用户对应的医生信息 appointment = get_object_or_404(Appointment, id=appointment_id) if request.method == 'POST': diagnosis = request.POST.get('diagnosis') appointment.diagnosis = diagnosis appointment.status = 'done' # 状态改为已完成 appointment.save() return redirect('/doctor/today/') return render(request, 'doctor/finish_visit.html', {'appointment': appointment})

患者挂号时则要处理号源扣减。常见写法是先查remaining是否大于 0,再创建挂号记录并减一。但高并发时这种“先查后减”会超卖,稳妥做法是加事务和select_for_update:

from django.db import transaction @transaction.atomic def create_appointment(request, schedule_id): schedule = Schedule.objects.select_for_update().get(id=schedule_id) if schedule.remaining <= 0: return render(request, 'patient/book.html', {'error': '号源已满'}) # 创建挂号记录并扣减号源 Appointment.objects.create( patient=request.user.patientprofile, schedule=schedule, visit_date=schedule.work_date, status='pending' ) schedule.remaining -= 1 schedule.save() return redirect('/patient/my/')

select_for_update是在事务里锁住这条排班记录,直到提交才释放。毕设里可能不会考这么深,但你在论文测试章节写“通过事务防止号源超卖”,会让整个系统设计的完整度高一个档次。

5. 常见问题排查:跑不起来时先查这五个位置

5.1 MySQL 8 认证插件不兼容:登录直接报错

现象:启动 Django 后访问页面,数据库操作报Access denied for user 'root'@'localhost',密码明明是对的。

原因:MySQL 8 默认使用caching_sha2_password认证插件,而旧版mysqlclient或 PyMySQL 不支持该插件,连接直接失败。

解决:两个方案选一个。在 MySQL 里把账号认证方式改回mysql_native_password,或者升级 Python 侧的数据库驱动。推荐升级驱动:pip install --upgrade mysqlclient,再重启runserver。改认证方式的语句是:

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的密码'; FLUSH PRIVILEGES;

这个坑几乎每个用 MySQL 8 + Django 3/4 的人都会踩一次,源码包自带的说明文档里如果没有提,建议你自己先查mysqlclient版本。

5.2 字符集没对齐:页面中文全变问号

现象:登录取到中文用户名,页面渲染成???,MySQL 里查出来也是乱码。

原因:数据库、表、连接三处字符集不一致。常见组合是 Django 连接用 utf8mb4,但建库时用了默认 latin1 或 utf8,字段存储时就丢了字符。

解决:建库时显式指定,注意这是数据库侧操作,在CREATE DATABASE时就要定好:

CREATE DATABASE hospital_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

同时确认settings.py里OPTIONS有'charset': 'utf8mb4'。老库改起来麻烦,直接删库重建最快,开发阶段数据丢了也不心疼。

5.3 session 掉线:一刷新就要重新登录

现象:登录成功后跳转首页,刷新一次又跳回登录页,浏览器里也没有 sessionid cookie。

原因:通常是settings.py中SESSION_ENGINE或SESSION_COOKIE_AGE配置异常,也可能是session中间件顺序不对。更隐蔽的原因是SECRET_KEY每次启动都变(有的源码会从环境变量读,没设置就随机生成)。

解决:先看MIDDLEWARE里有没有django.contrib.sessions.middleware.SessionMiddleware,再看INSTALLED_APPS里有没有django.contrib.sessions,最后固定SECRET_KEY:

# settings.py SECRET_KEY = 'django-insecure-xxx' SESSION_COOKIE_AGE = 60 * 60 * 8 # 8 小时

固定SECRET_KEY后重启服务,再登录测试。注意改了SECRET_KEY会让之前所有 session 失效,属正常现象。

5.4 Admin 后台看不到表:改了 models 忘了一件事

现象:用超级管理员登录/admin/,只看到默认的 User 和 Group 表,自己建的医生表、挂号和排班表都没有。

原因:模型建好了,但对应 app 里的admin.py没有注册模型。Django 后台必须显式注册才能显示。

解决:在app_doctor/admin.py和app_patient/admin.py中补上:

from django.contrib import admin from .models import DoctorProfile, Schedule admin.site.register(DoctorProfile) admin.site.register(Schedule)

每次新建模型都要三步:models.py定义、admin.py注册、python manage.py makemigrations && migrate。少一步就会遇到这个情况,这属于毕设源码里最常见的低级遗漏。

5.5 改了代码不生效:runserver 的自动重载骗了你

现象:明明改了视图函数,刷新页面没变化;甚至删了某个print,后台日志还在打印。

原因:Django 开发服务器是支持自动重载的,但触发条件是文件变更事件被正确监听。在 Windows 上,如果 IDE 保存时只做了临时文件替换,监听可能失效;更常见的是你开了多个runserver进程,改动被旧进程霸占。

解决:彻底停掉所有 Python 进程,重新启动python manage.py runserver。还不行就检查端口占用:

lsof -i:8000 # macOS / Linux 查看占用 netstat -ano | findstr :8000 # Windows 查看占用

还有一坑是浏览器缓存,HTML 模板和静态文件会被缓存,强刷一次 Ctrl+Shift+R 再判断。代码不生效的问题,90% 是这三个原因:进程没重启、端口被占、浏览器缓存,按顺序排查最快。

6. 测试用例设计与运行维护:交付前的最后一遍检查

论文第 6 章的系统测试,很多同学直接复制别人的测试描述,其实自己跑一遍更简单。手工测试建议按功能模块列测试用例,这里给一份可以直接套用的表格:

模块测试步骤输入数据预期结果
注册访问注册页,填不存在的用户名和一致密码username: test01, password: 123456注册成功,跳转登录页
登录输入正确用户名密码test01 / 123456登录成功,进入首页
密码错误输入错误密码test01 / 000000提示“用户名或密码错误”
管理员新增医生管理员登录后,填写医生信息和科室姓名:张医生,科室:内科列表出现新增记录,医生端可见
患者挂号选择医生和时段,点击挂号内科、上午挂号成功,号源剩余减一
医生写病历在待就诊列表点击完成,填入诊断文本诊断内容状态变已完成,患者端可查看

测试通过的标准不只是“没报错”,还要看状态流转:挂号前号源数量、挂号后数量、完成后状态字段。建议把这三个数据点截图放进论文附录,比文字描述有说服力得多。

运行维护部分,开发环境调通后如果要打包演示,有几个关键配置必须改。settings.py中把DEBUG设为False,ALLOWED_HOSTS写你的服务器 IP 或域名;然后执行python manage.py collectstatic收集静态文件。很多人演示时页面没样式,就是忘了这一步。数据库的备份用 MySQL 的mysqldump即可,演示前导出、演示完导入,防现场翻车。

再说一个我的习惯。从那以后我每次拿到 Django 源码包,第一件事不是看代码,而是按顺序跑这三步:先python manage.py check验证配置,再migrate确认数据库能通,最后建一个超级用户进 Admin 后台看每个模型都注册齐了。这三步走通,代码层面的坑已经排掉一大半。这个“先配置后业务”的排查顺序,能帮你隔离开环境问题和业务逻辑问题——希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/23 14:04:54

KEIL批处理脚本:编译后自动命名固件并打包,告别手动改版本号

简介&#xff1a;面向使用KEIL进行STM32等ARM嵌入式开发的工程师&#xff0c;这份资源提供了一套“程序名版本号时间自动打包”的完整实践方案&#xff0c;解决每次编译后手动修改版本号、逐个压缩备份文件既繁琐又易错的问题。压缩包共215个文件、约1000KB&#xff0c;包含c/h…

作者头像 李华
网站建设 2026/10/20 16:18:35

VSCODE database client 表数据无法显示问题及解决方法

最近在使用 VS Code 的 Database Client 扩展查看数据库表时&#xff0c;遇到了一个奇怪的问题&#xff1a;在当前项目窗口中&#xff0c;表数据无法正常显示&#xff0c;但切换到另一个窗口或项目后&#xff0c;功能又恢复正常。解决方法&#xff1a;打开帮助->切换开发人员…

作者头像 李华