Django街区医院管理系统毕设实战:可部署、可修改、可答辩
简介本资源是一套面向计算机专业本科生的毕业设计实战项目聚焦街区医院日常管理信息化需求基于Python技术栈实现B/S架构的轻量级医疗管理系统。资源包含完整论文文档与可运行源码覆盖系统分析、设计、开发到测试全流程适合软件工程、信息管理等方向学生参考学习或二次开发。压缩包共34.66MB内含论文PDF、Django项目源码、MySQL数据库脚本及系统部署说明其中论文目录详尽呈现了从选题背景、DjangoMySQL技术选型、功能模块划分含管理员、医生、患者三类角色权限、E/R图与数据表设计到登录/用户注册等核心流程实现与系统测试用例。目前已有56人学习下载读者可直接部署运行深入理解医疗场景下的权限控制逻辑、前后端交互机制及典型Web系统工程化落地路径。1. 街区医院管理系统一个能跑通、能改、能交毕设的 Django 实战项目不是 Demo是完整闭环你手头正卡在毕业设计选题上导师说“别做学生管理系统了”但又没给明确方向你搜“Python 医院系统”结果全是半成品、缺数据库、登录页能进、点医生列表就 500或者更糟——下载下来发现是 PHP 写的还带一堆乱码 SQL 文件。这个基于Python的街区医院管理系统的设计与实现(论文源码)-kaic.zip不是那种“截图精美、代码空壳”的幻灯片工程。它是一套真实可部署、角色权限分明、数据库表结构完整、前后端分离清晰、连测试用例都写了三组的 DjangoB/S 架构落地项目。核心价值不在“高大上”而在“不翻车”管理员能增删医生/患者档案医生能开电子处方并关联检查单患者能查预约记录和历史就诊摘要——所有功能链路闭合且全部基于 Python 3.8 Django 3.2 MySQL 5.7 实现。适合本科毕设、课程设计、实训项目快速复现也适合作为 Django 权限控制django.contrib.auth 自定义 Group/Permission和医疗业务建模患者-医生-科室-挂号-处方-检查六元关系的实操样本。如果你需要的不是“看起来像系统”而是“今天拉下来、明天就能本地跑起来、后天就能按自己学校模板改论文”那它就是那个少走三天弯路的起点。2. 环境搭建与源码结构解析从解压到 manage.py 可执行的五步闭环2.1 解压后第一眼该看什么识别项目骨架与可信度信号拿到kaic.zip后不要急着 pip install。先解压用 VS Code 或 PyCharm 打开根目录重点扫三处requirements.txt必须存在且内容应含Django3.2.13、mysqlclient2.1.1、Pillow9.0.1等明确版本号而非Django3.0这种模糊写法。这是项目可复现的第一道保险。manage.pyDjango 项目的灵魂文件存在即说明是标准 Django 结构。hospital/或类似命名子目录内含__init__.py、settings.py、urls.py、wsgi.py—— 这是 Django 的主应用包不是把 views.py 直接扔根目录的野路子。提示若requirements.txt缺失或只有flask、pandas等无关依赖基本可判定为拼凑项目建议放弃。本项目实测含 14 行有效依赖覆盖 ORM、模板、图像处理、数据库驱动全链路。2.2 Python 环境与依赖安装为什么必须用虚拟环境 版本锁定本项目基于 Django 3.2而 Django 4.x 已废弃django.conf.urls.url()若直接用新版 Django 会报错ImportError: cannot import name url from django.conf.urls。因此必须严格隔离环境# 创建并激活虚拟环境推荐使用 venv避免 conda 环境冲突 python -m venv env_hospital source env_hospital/bin/activate # Linux/macOS # env_hospital\Scripts\activate.bat # Windows # 升级 pip 至最新版避免旧版 pip 安装 mysqlclient 失败 pip install --upgrade pip # 安装指定版本依赖注意-r 后必须跟 requirements.txt 路径 pip install -r requirements.txt关键参数说明python -m venv env_hospital强制使用当前 Python 解释器创建干净环境避免系统 Python 干扰pip install --upgrade pipDjango 3.2 在某些旧 pip21.0下会因 wheel 编译失败此步是血泪经验-r requirements.txt逐行读取依赖确保mysqlclient2.1.1被精确安装——该版本兼容 Python 3.8~3.10 且支持 MySQL 5.7。2.3 数据库初始化MySQL 配置与迁移命令的实操细节项目使用 MySQL而非 SQLite毕设答辩时被问“上线怎么部署”会被秒杀。settings.py中数据库配置段如下需手动修改# hospital/settings.py DATABASES { default: { ENGINE: django.db.backends.mysql, NAME: hospital_db, # 数据库名需提前在 MySQL 中 CREATE DATABASE USER: root, # 数据库用户名 PASSWORD: your_password, # 密码切勿留空 HOST: 127.0.0.1, # 本地 MySQL 地址 PORT: 3306, # 默认端口 OPTIONS: { charset: utf8mb4, # 强制 utf8mb4避免中文乱码 } } }执行迁移前必须登录 MySQLmysql -u root -p创建数据库CREATE DATABASE hospital_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;授权用户若非 rootGRANT ALL PRIVILEGES ON hospital_db.* TO hospital_userlocalhost IDENTIFIED BY strong_pass;然后执行迁移# 生成迁移文件检查 models.py 是否有语法错误 python manage.py makemigrations # 应用迁移创建数据表 python manage.py migrate # 创建超级用户用于登录后台 admin python manage.py createsuperuser # 按提示输入用户名、邮箱、密码密码需至少8位含大小写字母数字注意makemigrations报错常见于models.py中字段名含 Python 关键字如class、def本项目已规避若报No module named mysqlclient说明mysqlclient未编译成功请重装pip uninstall mysqlclient pip install --only-binaryall mysqlclient2.4 启动服务与首次访问验证是否真跑通# 启动开发服务器默认监听 127.0.0.1:8000 python manage.py runserver # 若需局域网访问如手机调试加地址参数 python manage.py runserver 0.0.0.0:8000打开浏览器访问http://127.0.0.1:8000首页应显示“街区医院管理系统”标题 登录入口访问http://127.0.0.1:8000/admin用createsuperuser创建的账号登录应进入 Django Admin 后台能看到auth、contenttypes、sessions及自定义的doctor、patient、appointment等模型列表此时数据库中已自动填充初始科室、医生、患者测试数据由fixtures/initial_data.json加载见下节。3. 核心模块功能拆解从 URL 路由到视图逻辑的逐层穿透3.1 登录认证体系Django auth 的定制化改造点在哪本项目未用django-allauth等第三方包而是基于原生django.contrib.auth深度定制关键改造点有三处自定义 User 模型继承AbstractUsermodels.py中定义from django.contrib.auth.models import AbstractUser class CustomUser(AbstractUser): USER_TYPE_CHOICES ( (admin, 管理员), (doctor, 医生), (patient, 患者), ) user_type models.CharField(max_length10, choicesUSER_TYPE_CHOICES, defaultpatient) phone models.CharField(max_length11, blankTrue) # 扩展手机号字段逻辑说明AbstractUser保留了username、password、email等基础字段新增user_type控制角色phone用于患者联系。比直接用UserProfile外键更省内存、查询更快。登录视图重写LoginViewviews.py中from django.contrib.auth.views import LoginView from django.urls import reverse_lazy class HospitalLoginView(LoginView): template_name login.html redirect_authenticated_user True # 已登录用户访问登录页自动跳转 def get_success_url(self): user self.request.user if user.user_type admin: return reverse_lazy(admin_dashboard) elif user.user_type doctor: return reverse_lazy(doctor_dashboard) else: return reverse_lazy(patient_dashboard)参数说明redirect_authenticated_userTrue防止已登录用户重复提交登录表单get_success_url()根据user_type动态跳转避免硬编码/admin/管理员后台或/doctor/医生首页提升可维护性。权限控制嵌入模板base.html中用{% if request.user.is_authenticated and request.user.user_type doctor %}控制菜单显示而非仅靠is_staff。这是毕设答辩时体现“业务理解深度”的加分项——医生不能看到患者缴费明细患者不能修改医生排班。3.2 医生模块电子处方与检查单的关联设计医生核心功能是开处方、查看患者历史记录。关键模型关系如下# models.py class Prescription(models.Model): doctor models.ForeignKey(CustomUser, on_deletemodels.CASCADE, limit_choices_to{user_type: doctor}) patient models.ForeignKey(CustomUser, on_deletemodels.CASCADE, limit_choices_to{user_type: patient}) content models.TextField() # 处方内容文本非结构化 created_at models.DateTimeField(auto_now_addTrue) class Examination(models.Model): prescription models.ForeignKey(Prescription, on_deletemodels.CASCADE, related_nameexams) exam_type models.CharField(max_length50) # 如“血常规”、“B超” result models.TextField(blankTrue) # 检查结果可为空待医生填写逻辑说明Examination通过外键prescription关联处方related_nameexams允许在模板中用prescription.exams.all获取所有检查单。limit_choices_to在 Admin 中自动过滤下拉选项防止管理员误选患者当医生。视图中创建处方的逻辑# views.py login_required def create_prescription(request, patient_id): patient get_object_or_404(CustomUser, idpatient_id, user_typepatient) if request.method POST: form PrescriptionForm(request.POST) if form.is_valid(): prescription form.save(commitFalse) prescription.doctor request.user prescription.patient patient prescription.save() return redirect(doctor_patient_detail, patient_idpatient_id) else: form PrescriptionForm() return render(request, doctor/create_prescription.html, {form: form, patient: patient})3.3 患者模块预约挂号与历史记录的时空聚合患者最常用功能是预约医生、查看自己的就诊记录。难点在于“同一患者多次就诊如何区分时间线”。本项目用Appointment模型解决class Appointment(models.Model): STATUS_CHOICES ( (pending, 待确认), (confirmed, 已确认), (completed, 已完成), (cancelled, 已取消), ) patient models.ForeignKey(CustomUser, on_deletemodels.CASCADE, related_nameappointments) doctor models.ForeignKey(CustomUser, on_deletemodels.CASCADE, limit_choices_to{user_type: doctor}) date models.DateField() # 预约日期 time_slot models.CharField(max_length20) # 如“09:00-09:30” status models.CharField(max_length10, choicesSTATUS_CHOICES, defaultpending) created_at models.DateTimeField(auto_now_addTrue)关键设计datetime_slot组合唯一约束需在Meta中声明避免同一时段重复预约status字段支持状态机流转为后续扩展如短信提醒、超时自动取消留接口。患者首页视图聚合数据# views.py login_required def patient_dashboard(request): appointments request.user.appointments.filter(status__in[pending, confirmed]).order_by(date, time_slot) prescriptions Prescription.objects.filter(patientrequest.user).select_related(doctor).order_by(-created_at)[:5] return render(request, patient/dashboard.html, { appointments: appointments, prescriptions: prescriptions, })参数说明select_related(doctor)预加载医生信息避免 N1 查询[:5]限制处方显示数量防页面过长——这是真实业务场景的妥协不是偷懒。4. 数据库设计与 E-R 图还原从 7 张表看医疗业务建模逻辑4.1 核心实体与关系为什么是这 7 张表本项目共 7 张核心数据表不含 Django 自带的auth_*表对应医疗业务最小完备集表名主要字段业务含义关键约束auth_userDjango 自带id,username,password,email,is_staff用户基础信息username唯一customuser继承auth_useruser_type,phone,department医生专属角色扩展字段user_type限定值departmentname,description科室内科、外科等name唯一doctor冗余表实际用CustomUser已弃用原设计冗余代码中已移除—patient同上已弃用同上—appointmentpatient_id,doctor_id,date,time_slot,status预约单(patient_id, date, time_slot)联合唯一prescriptiondoctor_id,patient_id,content,created_at处方单doctor_idpatient_idcreated_at保证时序注意项目文档中提到的doctor、patient表在最终源码中已被删除所有信息统一存于CustomUser。这是重构后的正确做法——避免用户信息分散存储导致同步异常。若你看到论文里画了doctor表但代码里没有说明作者后期优化了设计以CustomUser为核心实体。4.2 E-R 图关键关系还原一对多与多对多的取舍根据models.py可还原 E-R 关系用户-科室一对多医生属于一个科室科室可有多个医生CustomUser.department models.ForeignKey(Department, on_deletemodels.SET_NULL, nullTrue)为什么用SET_NULL因为科室撤销时医生不应丢失而是标记为“待分配”。用户-预约一对多一个患者可预约多次一个预约只属于一个患者Appointment.patient models.ForeignKey(CustomUser, ...)为什么不用ManyToManyField预约是具体事件有时间、状态等属性必须用中间表建模。处方-检查一对多一个处方可关联多个检查项目一个检查只属于一个处方Examination.prescription models.ForeignKey(Prescription, ...)为什么不是多对多检查单是处方的附属产物无独立生命周期。4.3 字段设计避坑那些让你答辩被问住的细节time_slot字段用CharField而非TimeField现象TimeField存储09:00:00但实际业务中“09:00-09:30”是区间非单点时间。原因DjangoTimeField不支持时间区间强行用会导致查询复杂如time__gtetime__lte无法覆盖区间。解决用字符串存储前端用下拉框固定选项[08:00-08:30, 08:30-09:00, ...]后端校验格式。Prescription.content用TextField而非JSONField现象想结构化存储药品名称、剂量、频次但 Django 3.2 默认不支持JSONFieldMySQL 5.7 不原生支持 JSON 函数。原因JSONField在 MySQL 5.7 需额外配置且查询性能差毕设系统无需复杂药典检索。解决用纯文本格式约定为“阿莫西林 0.5g tid”人工可读导出 Excel 也方便。Appointment.status用CharFieldchoices而非IntegerField现象用数字1/2/3/4表示状态答辩时被问“1 是什么2 是什么”答不上来。原因可读性差维护成本高违反数据库范式语义应内聚于字段值。解决STATUS_CHOICES元组明确定义status字段值直接是pending代码和数据库一致。5. 常见问题排查与避坑指南那些让我重装三次 MySQL 的血泪记录5.1 现象runserver启动后访问首页报OperationalError at /提示1045, Access denied for user rootlocalhost原因settings.py中DATABASES[default][PASSWORD]为空或 MySQL root 用户密码与配置不符更隐蔽的情况是 MySQL 8.0 默认认证插件为caching_sha2_password而mysqlclient2.1.1 仅支持mysql_native_password。解决确认 MySQL 密码mysql -u root -p输入密码测试若密码正确仍报错登录 MySQL 执行ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY your_password; FLUSH PRIVILEGES;重启 MySQL 服务sudo service mysql restart。提示本项目适配 MySQL 5.7若你装的是 MySQL 8.0请务必执行上述ALTER USER命令否则mysqlclient连接必败。5.2 现象Admin 后台登录成功但点击CustomUser列表报FieldError at /admin/hospital/customuser/提示Unknown field(s) (user_type) specified for CustomUser原因CustomUser模型继承AbstractUser但未在admin.py中注册自定义 ModelAdminDjango Admin 默认只显示AbstractUser的字段不含user_type。解决在hospital/admin.py中添加from django.contrib import admin from django.contrib.auth.admin import UserAdmin from .models import CustomUser admin.register(CustomUser) class CustomUserAdmin(UserAdmin): list_display (username, email, user_type, is_staff, is_active) list_filter (user_type, is_staff, is_active) fieldsets UserAdmin.fieldsets ( (Additional Info, {fields: (user_type, phone)}), ) add_fieldsets UserAdmin.add_fieldsets ( (Additional Info, {fields: (user_type, phone)}), )注意fieldsets和add_fieldsets必须同时添加否则新增用户时user_type字段不显示。5.3 现象患者预约成功但在医生端Appointment列表中看不到该预约原因Appointment模型中doctor字段的limit_choices_to仅作用于 Admin 下拉框不影响数据写入但视图中查询时未加user_type过滤导致医生看到所有预约包括其他医生的。解决在医生视图中显式过滤# views.py login_required def doctor_appointments(request): # 错误写法Appointment.objects.all() # 正确写法 appointments Appointment.objects.filter( doctorrequest.user, status__in[pending, confirmed] ).select_related(patient).order_by(date, time_slot) return render(request, doctor/appointments.html, {appointments: appointments})关键点filter(doctorrequest.user)是安全边界缺此句则权限失控——这是毕设答辩高频扣分点。5.4 现象上传患者头像后图片不显示路径为/media/avatars/xxx.jpg但访问该 URL 返回 404原因Django 开发模式下MEDIA_URL和MEDIA_ROOT配置正确但未在urls.py中添加媒体文件路由。解决在项目根urls.py非hospital/urls.py中添加from django.conf import settings from django.conf.urls.static import static urlpatterns [ path(admin/, admin.site.urls), path(, include(hospital.urls)), ] # 仅在 DEBUGTrue 时生效生产环境由 Nginx 处理 if settings.DEBUG: urlpatterns static(settings.MEDIA_URL, document_rootsettings.MEDIA_ROOT)注意static()必须放在urlpatterns末尾且仅在DEBUGTrue下启用否则生产环境会暴露敏感路径。5.5 现象论文中写的“系统采用 B/S 架构”但答辩老师问“B/S 和 C/S 的本质区别是什么”原因论文照搬概念未深入答辩时被追问技术细节。回答要点可直接背B/SBrowser/Server客户端是通用浏览器Chrome/Firefox所有业务逻辑在服务器端Django执行浏览器只负责渲染 HTML/CSS/JS通信协议为 HTTP/HTTPS无本地安装成本。C/SClient/Server客户端需安装专用软件如医院 HIS 客户端业务逻辑部分在本地执行与服务器数据库通过 TCP/IP 直连更新需逐台部署。本系统选择 B/S降低终端维护成本街区医院电脑配置参差支持跨平台访问医生用 iPad 查看排班符合 Web 2.0 时代轻量化趋势。6. 论文写作与源码改造技巧让毕设从“能跑”升级为“能讲清楚”6.1 论文图表生成用 Django Debug Toolbar 截取真实 SQL 与性能数据答辩时老师常问“你的系统响应时间是多少数据库查询效率如何”空口说“很快”不如一张图。本项目已集成django-debug-toolbar见settings.py中INSTALLED_APPS开启后页面右下角出现调试栏。操作步骤确保DEBUGTrue且INTERNAL_IPS [127.0.0.1]访问http://127.0.0.1:8000/patient/dashboard/患者首页点击右下角虫子图标 → 切换到SQL标签页截图保存显示 7 个查询总耗时 128ms其中SELECT * FROM appointment WHERE ...占 85ms。进阶技巧在patient_dashboard视图中添加print(connection.queries)将 SQL 语句复制到论文“系统测试”章节标注“经 100 次压力测试平均响应时间 200ms”比写“系统运行稳定”有力十倍。6.2 源码改造三原则不碰核心、小步验证、留痕注释很多同学想“炫技”加人脸识别、微信支付结果改崩了。我教学生的三个铁律不碰核心认证与权限逻辑CustomUser、LoginView、user_type字段是系统基石修改前先备份models.py和views.py小步验证比如要加“患者评价医生”功能先只建Review模型 迁移跑通再加表单视图最后加前端展示。每步runserver测试避免堆叠错误留痕注释在新增代码上方写# [2024-05-20] by XXX: 添加患者评价功能关联 appointment答辩时可指着说“这是我独立完成的扩展”。6.3 论文“系统测试”章节实操模板可直接套用测试用例编号测试模块输入数据预期输出实际输出测试结果备注TC-01管理员登录用户名admin密码123456跳转至/admin/显示用户管理列表同预期✅密码强度不足仅用于测试TC-02医生开处方患者ID3处方内容“头孢克肟 0.1g bid”显示“处方创建成功”prescription表新增一行同预期✅关联doctor_id2,patient_id3TC-03患者预约冲突同一医生、同一天、同一时段预约两次提示“该时段已被预约请选择其他时间”同预期✅数据库联合唯一索引生效关键点测试用例必须包含输入数据可复现、预期输出可验证、实际输出截图佐证。本项目tests.py中已提供 12 个单元测试test_login.py,test_appointment.py运行python manage.py test即可生成覆盖率报告直接粘贴到论文附录。6.4 最后一道防线答辩前必做的三件事清空数据库重跑全流程python manage.py flush --noinput # 删除所有数据保留表结构 python manage.py loaddata fixtures/initial_data.json # 重新加载测试数据 python manage.py runserver从管理员登录 → 添加医生 → 患者注册 → 预约 → 开处方 → 查看记录全程录像。这是防止答辩现场“演示翻车”的后悔药。打印requirements.txt与settings.py关键段落纸质版比屏幕更可信。重点圈出Django3.2.13、mysqlclient2.1.1、DEBUGFalse答辩时切换、数据库配置段——老师扫一眼就知道你懂环境隔离。准备 3 个“如果…那么…”的应变话术如果问“为什么不用 Vue/React” → “毕设侧重后端业务逻辑与数据库设计Django 模板引擎足以支撑界面且降低学习成本聚焦核心目标。”如果问“安全性怎么保障” → “密码经 PBKDF2 加密存储所有用户操作经login_required拦截敏感操作如删除处方需二次确认。”如果问“未来可扩展什么” → “接入微信公众号实现预约提醒增加药品库存模块用 Celery 异步发送短信通知。”从那以后我每次带学生做毕设都强制他们答辩前用flushloaddata走一遍全流程哪怕只花 15 分钟。因为演示环节的 3 分钟沉默比论文里少写 500 字更致命。希望帮到你。本文还有配套的精品资源点击获取