Django医院信息管理系统开发实战:从ORM设计到权限控制全解析
发布时间:2026/10/2 22:28:01来源:尧图网络
1. 项目概述与思路拆解先说结论用 Python 和 Django 做医院信息管理系统是初学者进阶到中级最好的实战课题之一。这类系统表面看是一堆增删改查但真正做起来会涉及权限控制、多表关联、业务状态流转、事务一致性这些核心问题做完一遍你对 Web 开发的认知会上一个台阶。1.1 这类项目最值得折腾的三个原因第一医院信息管理系统的业务边界非常清晰。科室、医生、患者、挂号、病历、收费每一个模块都有明确的数据结构和操作流程不像“电商系统”那样要纠结商品规格、秒杀、支付回调一堆分支。你只需要把核心流程跑通就能得到一个真正能演示、能交付的完整系统成就感来得很快。第二它天然包含“多角色”和“权限”这两个概念。医生看自己名下的患者患者看自己的病历管理员管全局——这不是刻意加难度而是这个场景本身就长这样。Django 自带 User 模型和权限框架你在做项目的过程中几乎必然要用到auth模块去扩展用户、分组、权限这部分经验是工作里天天用的。第三它逼着你面对“关系型数据”建模。患者和挂号记录是 1 对多医生和科室是多对 1病历和患者是 1 对 1这些关系用 Django ORM 建模时非常自然。等你写完ForeignKey、OneToOneField、ManyToManyField再跑一遍makemigrations你对关系型数据库的理解就不再是课本上的概念了。1.2 技术选型为什么是 Django而不是 Flask 或 FastAPI我经常被问到这个问题。对医院管理系统这种业务逻辑重、表单多、后台管理需求强的项目Django 几乎是首选。Django 自带 Admin 后台。医院管理系统天然需要一个管理后台来维护科室、药品、医生排班等基础数据Django Admin 只要配好模型就能直接用省掉了一大半重复的 CRUD 页面。你自己写这些页面至少要多花两三天而且远不如 Admin 严谨。Django 的 ORM 足够成熟。多表查询、条件筛选、聚合统计、事务控制这些在业务系统里高频出现的能力Django ORM 都封装得很顺手。当然有人会说 FastAPI 用 SQLAlchemy 也能做但它要自己组装的东西更多项目进度会慢不少。Django 的表单和验证体系对这类系统简直是量身定做。患者填挂号信息、医生填病历每个字段都要校验Django 的forms.ModelForm可以从模型直接生成表单再配合clean_钩子做自定义验证效率非常高。再说数据库选型。开发阶段直接用 SQLite 就够了Django 切换数据库就是改个DATABASES配置的事。但要注意如果在模型里用了 SQLite 特有字段或者依赖了某些特性后面切 MySQL 会踩坑。我的习惯是从一开始就按 MySQL 的语法习惯建模字段类型只用通用的那些避免后期返工。1.3 功能模块划分做项目之前先画清楚边界这一步省下来的时间远比想象中多。我建议把系统拆成这么几个核心模块用户认证与角色管理扩展 DjangoUser模型区分管理员、医生、患者三种角色走各自的登录入口或登录后跳转不同首页。科室与医生管理维护科室列表设置科室下的医生支持医生排班可选。患者管理患者的注册、信息维护、就诊历史查询。挂号管理患者选择科室、医生和时间段进行挂号挂号状态约束为待就诊、已就诊、已取消。病历管理医生为已就诊患者录入病历病历和挂号记录关联支持按患者或医生检索。计费管理可选按挂号费和药费生成账单简单记录收款状态。这几个模块如果都做完你的系统已经具备了三甲医院门诊系统 90% 的核心逻辑。如果你时间有限至少要把前五个模块做扎实尤其是“挂号→就诊→写病历”这条主链路一定不能断。2. 环境准备与项目初始化这一节与其说讲步骤不如说讲思路。环境配置其实很快但很多人卡在了 Python 版本、虚拟环境和 Django 版本搭配上。2.1 Python 版本和 Django 版本的搭配一句话Python 3.10 以上 Django 4.2 LTS或者 Python 3.12 Django 5.x这俩组合比较稳。Django 4.2 是长期支持版到 2026 年才结束维护对新手最友好5.x 功能更新但资料相对少一点。我推荐直接用 Django 4.2 LTS你在网上搜到的大多数资料、代码片段、第三方应用在这个版本上都不容易出兼容问题。怎么检查当前安装的 Python 版本python --version如果是 3.8 或 3.9也够用但要注意 Django 4.2 官方要求 Python 3.8 以上5.x 要求 3.10 以上。如果你机器上 Python 版本偏低建议直接装新版而不是去迁就旧版本。2.2 虚拟环境配置虚拟环境是开发这类项目的底线要求。不是为了装 X是真的能避免你后期“这个包为什么装不上”“版本冲突了”之类的问题。我一般用venvPython 自带不需要额外装。mkdir hospital_system cd hospital_system python -m venv venvWindows 激活venv\Scripts\activatemacOS / Linux 激活source venv/bin/activate激活后命令行会有(venv)前缀。接下来装 Djangopip install django4.2如果想顺便做接口调试可以再装djangorestframework和django-cors-headers不过我的建议是第一次做这个项目尽量少依赖第三方应用先把 Django 本身的套路跑熟再上 DRF 也不迟。2.3 创建项目和 App 的规划创建项目django-admin startproject config .注意我最后加了一个点表示在当前目录创建配置文件而不是再套一层目录。这样目录结构更清爽。创建 Apppython manage.py startapp accounts python manage.py startapp departments python manage.py startapp patients python manage.py startapp appointments python manage.py startapp medical_records之所以按业务模块拆 App而不是只搞一个app01是因为 Django 的设计哲学就是“App 之间要尽量独立、可复用”。后面你给medical_records加功能时不影响patients给appointments加状态字段时也不需要改别的 App。这种拆分方式在项目变大以后会越来越觉得值。把 App 注册进config/settings.py的INSTALLED_APPSINSTALLED_APPS [ django.contrib.admin, django.contrib.auth, django.contrib.contenttypes, django.contrib.sessions, django.contrib.messages, django.contrib.staticfiles, accounts, departments, patients, appointments, medical_records, ]顺便把语言和时区改掉不然后台页面全是英文、时间差八个小时LANGUAGE_CODE zh-hans TIME_ZONE Asia/Shanghai USE_TZ True然后跑一下初始迁移创建 Django 自带的用户和相关表python manage.py migrate python manage.py createsuperuser这里创建的超级用户是后面进入 Admin 后台的基础账号先记住用户名密码。3. 核心模型设计与 Django ORM 实战这是整个系统最见功夫的部分。模型设计的好坏决定了后面写业务的顺畅程度。我先给出一套可以直接用的模型定义然后逐条解释为什么这么设计。3.1 用户与角色的模型扩展Django 自带User模型有用户名、密码、邮箱等字段但缺少“角色”。我的做法是用配置文件指定一个自定义用户模型叫作UserProfile和User用OneToOneField关联而不是直接修改自带的User。这样做的好处是安全、可扩展以后想加“头像”“手机号”等字段时不至于重构整个认证系统。先在accounts/models.py里写from django.contrib.auth.models import User from django.db import models class UserProfile(models.Model): ROLE_CHOICES [ (admin, 管理员), (doctor, 医生), (patient, 患者), ] user models.OneToOneField(User, on_deletemodels.CASCADE, related_nameprofile) role models.CharField(max_length20, choicesROLE_CHOICES, defaultpatient) phone models.CharField(max_length20, blankTrue) real_name models.CharField(max_length50, blankTrue) def __str__(self): return f{self.user.username}: {self.role}然后在config/settings.py里加一行AUTH_PROFILE_MODULE accounts.UserProfile严格来说 Django 的AUTH_PROFILE_MODULE在新版本里已经不太用真正的做法是设置AUTH_USER_MODEL。但那种方式需要自定义AbstractUser对初学者来说反而更绕。我的方案是在视图层通过request.user.profile.role来区分角色够用也不折腾。3.2 科室、医生、患者、挂号、病历模型核心模型我建议这么设计# departments/models.py class Department(models.Model): name models.CharField(max_length100, uniqueTrue, verbose_name科室名称) location models.CharField(max_length200, blankTrue, verbose_name位置) description models.TextField(blankTrue, verbose_name科室简介) created_at models.DateTimeField(auto_now_addTrue) class Meta: verbose_name 科室 verbose_name_plural verbose_name def __str__(self): return self.name # departments/models.py 中追加 class Doctor(models.Model): user_profile models.OneToOneField(accounts.UserProfile, on_deletemodels.CASCADE) department models.ForeignKey(Department, on_deletemodels.PROTECT, related_namedoctors) title models.CharField(max_length50, blankTrue, verbose_name职称) schedule models.CharField(max_length200, blankTrue, verbose_name出诊时间) def __str__(self): return f{self.user_profile.real_name} ({self.department.name})注意department用的on_deletemodels.PROTECT意思是如果该科室下还有医生就不允许直接删掉科室防止产生悬空数据。这是真实业务里非常重要的约束很多人一开始图省事全用CASCADE结果删一个科室把医生和挂号记录全带没了。患者模型# patients/models.py class Patient(models.Model): user_profile models.OneToOneField(accounts.UserProfile, on_deletemodels.CASCADE) id_number models.CharField(max_length18, verbose_name身份证号, uniqueTrue) birth_date models.DateField(nullTrue, blankTrue) gender models.CharField(max_length10, choices[(M, 男), (F, 女)], defaultM) address models.CharField(max_length200, blankTrue) class Meta: verbose_name 患者 verbose_name_plural verbose_name def __str__(self): return self.user_profile.real_name挂号记录是整个系统的枢纽模型所有业务流程都挂在它上面# appointments/models.py class Appointment(models.Model): STATUS_CHOICES [ (pending, 待就诊), (done, 已就诊), (cancelled, 已取消), ] patient models.ForeignKey(patients.Patient, on_deletemodels.CASCADE, related_nameappointments) doctor models.ForeignKey(departments.Doctor, on_deletemodels.CASCADE, related_nameappointments) date models.DateField(verbose_name就诊日期) time_slot models.CharField(max_length20, verbose_name时间段) status models.CharField(max_length20, choicesSTATUS_CHOICES, defaultpending) created_at models.DateTimeField(auto_now_addTrue) class Meta: verbose_name 挂号记录 verbose_name_plural verbose_name ordering [-created_at] constraints [ models.UniqueConstraint(fields[doctor, date, time_slot], nameunique_doctor_slot) ] def __str__(self): return f{self.patient} - {self.doctor} - {self.date} {self.time_slot}这里的UniqueConstraint是重点它保证了同一个医生在同一个日期的同一个时间段只能有一条挂号记录从数据库层面锁死重复挂号的漏洞。只靠应用层判断并发时会出问题这个约束是必须的。病历模型# medical_records/models.py class MedicalRecord(models.Model): appointment models.OneToOneField(appointments.Appointment, on_deletemodels.CASCADE, related_namemedical_record) doctor models.ForeignKey(departments.Doctor, on_deletemodels.CASCADE) patient models.ForeignKey(patients.Patient, on_deletemodels.CASCADE) diagnosis models.TextField(verbose_name诊断内容) prescription models.TextField(blankTrue, verbose_name处方) created_at models.DateTimeField(auto_now_addTrue) class Meta: verbose_name 病历 verbose_name_plural verbose_name def __str__(self): return f病历-{self.patient} - {self.created_at:%Y-%m-%d}3.3 配套数据迁移的命令与经验模型写完后生成并执行迁移python manage.py makemigrations python manage.py migrate这里有一个踩坑经验如果迁移时提示NameError或者找不到某个模型多半是因为不同 App 之间的引用顺序不对。比如Doctor引用了accounts.UserProfile而accounts的迁移还没有生成就会报错。解决办法是按依赖顺序先迁移基础的 Apppython manage.py makemigrations accounts python manage.py makemigrations departments python manage.py makemigrations patients python manage.py makemigrations appointments python manage.py makemigrations medical_records python manage.py migrateDjango 的迁移系统会记录每个 App 的迁移状态只要按这个顺序跑一遍基本不会出幺蛾子。3.4 热门话题Django 执行查询与删除对象检索和删除是开发者每天都要做的事但在真实系统里“怎么查”比“查到什么”更重要。直接看代码查所有all_doctors Doctor.objects.all()按科室过滤医生doctors_in_cardiology Doctor.objects.filter(department__name心血管内科)注意这里用的是跨关系过滤department__name可以穿透到关联表。只要部门名存在这个查询就会自动 JOIN写起来和 ORM 一样顺滑。查某个患者最近五条挂号记录appointments Appointment.objects.filter(patient__user_profile__real_name张三).order_by(-created_at)[:5]这里也用了跨关系查询patient__user_profile__real_name一路穿透到用户真实姓名。性能上如果只是少量数据没有问题但数据量大时要考虑用select_related优化条数这个放到第 5 节讲。删除对象一般是先取对象再调delete()appt Appointment.objects.get(id10) appt.delete()如果要用查询方式批量删除Appointment.objects.filter(doctor_id3, statuscancelled).delete()但这里有个特别要提醒的坑delete()是数据库层面的批量操作它不会触发 Django 信号signals也不会逐个跑模型的delete方法。所以如果模型里存在级联删除相关逻辑直接批量删除要格外小心。更安全的做法是先查出要删的对象列表再逐个删这样能保证信号生效。另外Django ORM 中删除一个有外键指向它的对象默认是CASCADE行为会把关联的子记录一起删除。比如你删除一个Patient他名下的所有Appointment也会被连带删除。你要想清楚这是不是你要的效果。如果不想删牵连数据把外键的on_delete设为PROTECT这样系统会拒绝删除存在关联的父记录。4. 核心业务模块开发与登录认证模型只是骨架接下来要给系统注入真正的业务流程。这一节会把“登录注册 → 挂号 → 写病历 → 后台管理”这条链路串起来讲。4.1 用 Django 内置认证实现注册和登录登录和注册是医院信息系统的入口我用的也是 Django 内置的authenticate和login来做不需要从头写 session 逻辑。先看注册视图。一个账号同时对应一个User和一个UserProfile注册时一次性创建# accounts/views.py from django.contrib.auth.models import User from django.contrib.auth import login from django.shortcuts import render, redirect from .models import UserProfile def register(request): if request.method POST: username request.POST[username] password request.POST[password] real_name request.POST[real_name] phone request.POST[phone] role request.POST.get(role, patient) user User.objects.create_user(usernameusername, passwordpassword) profile UserProfile.objects.create( useruser, real_namereal_name, phonephone, rolerole ) login(request, user) return redirect(dashboard) return render(request, accounts/register.html)create_user会自动给密码加盐哈希千万不要用User.objects.create()或者手动改密码不然密码会明文存储这是安全大忌。登录视图用authenticate验证然后login建立会话def user_login(request): if request.method POST: username request.POST[username] password request.POST[password] user authenticate(request, usernameusername, passwordpassword) if user is not None: login(request, user) return redirect(dashboard) else: return render(request, accounts/login.html, {error: 用户名或密码错误}) return render(request, accounts/login.html)登录之后根据profile.role跳转到不同页面就是我推荐的区分角色的方式from django.contrib.auth.decorators import login_required login_required def dashboard(request): role request.user.profile.role if role doctor: return redirect(doctor_home) elif role patient: return redirect(patient_home) return render(request, admin_home.html)login_required装饰器非常好用只要没登录的用户访问该视图就会自动跳到settings.LOGIN_URL指定的登录页。不用自己在每个视图里写判断。4.2 被问到最多的“token”问题是怎么解决的热搜里有个很典型的词“django cookie 设置 token”。很多人做前后端分离或者手机 App 接入时会纠结应该用 session 还是 token。对于纯 Django 模板的传统项目我的建议是直接用 Cookie Session这是 Django 自带能力封装得很完善login(request, user)后浏览器会自动种下 sessionid cookie之后每次请求都携带这个 CookieDjango 自己识别。只有当你打算写 REST API 给前端 SPA 或手机端用的时候才需要引入 JWT。那种场景通常配合djangorestframework-simplejwt登录时返回 access token 和 refresh token。但我们在医院管理系统这个项目里如果还在用 Django 模板渲染页面折腾 JWT 属于过度设计给自己添麻烦。这里有一个实战细节如果你想给前端返回数据时带一个持久化的业务 token而不是用 Django session有一种很常见的做法是把生成 token 并通过response.set_cookie()返回给浏览器import secrets token secrets.token_hex(32) response redirect(dashboard) response.set_cookie(api_token, token, max_age3600, httponlyTrue, samesiteLax)注意到httponlyTrue是关键这个 cookie 客户端 JavaScript 读不到能有效防止 XSS 脚本偷走登录凭证。在没有特殊需求的情况下我个人更推荐把这个 token 存到数据库或缓存里和服务端做校验而不是只靠客户端传回就表示身份合法。4.3 挂号模块的业务逻辑和事务控制挂号的流程是这样的患者选择科室和医生 → 选择日期和时间段 → 提交挂号 → 生成 Appointment 记录。在提交时要解决两个关键问题重复挂号、并发抢占。先写视图# appointments/views.py from django.shortcuts import render, redirect, get_object_or_404 from django.contrib.auth.decorators import login_required from django.contrib import messages from .models import Appointment from departments.models import Doctor login_required def create_appointment(request): if request.method POST: doctor_id request.POST[doctor_id] date request.POST[date] time_slot request.POST[time_slot] doctor get_object_or_404(Doctor, iddoctor_id) patient request.user.profile.patient if Appointment.objects.filter(doctordoctor, datedate, time_slottime_slot, status__in[pending, done]).exists(): messages.error(request, 该时间段已被占用请选择其他时间) return redirect(create_appointment) appointment Appointment.objects.create( patientpatient, doctordoctor, datedate, time_slottime_slot, statuspending ) messages.success(request, f挂号成功就诊编号{appointment.id}) return redirect(patient_home) doctors Doctor.objects.select_related(department).all() return render(request, appointments/create.html, {doctors: doctors})这里的流程是先查“是否已存在未取消的挂号”再把数据插入。问题来了两个请求同时进来都看到没有记录然后同时插入就造成了超卖。数据库层的UniqueConstraint第 3.2 节定义的那个是最终防线它一旦发现重复就会抛IntegrityError。所以完整的写法应该把创建包在异常处理里from django.db import IntegrityError, transaction try: with transaction.atomic(): appointment Appointment.objects.create(...) except IntegrityError: messages.error(request, 该时间段刚刚被预约请刷新后重新选择) return redirect(create_appointment)transaction.atomic()把创建操作放进一个数据库事务中要么成功提交要么在出错时全部回滚。这虽然不是分布式锁那么高级但医院门诊这种单系统部署场景已经够用。4.4 病历录入与医生视角医生登录后看到的首页应该是“今天候诊列表”然后逐条把挂号状态从“待就诊”改成“已就诊”录入诊断和处方。列出待就诊列表login_required def doctor_home(request): doctor request.user.profile.doctor today timezone.localdate() pending_appts Appointment.objects.filter( doctordoctor, datetoday, statuspending ).select_related(patient__user_profile__user) return render(request, appointments/doctor_home.html, { pending_appts: pending_appts })写病历时只允许该挂号的医生操作防止越权login_required def write_record(request, appointment_id): appointment get_object_or_404(Appointment, idappointment_id) if request.user.profile.doctor ! appointment.doctor: return render(request, 403.html) if request.method POST: diagnosis request.POST[diagnosis] prescription request.POST[prescription] MedicalRecord.objects.create( appointmentappointment, doctorappointment.doctor, patientappointment.patient, diagnosisdiagnosis, prescriptionprescription ) appointment.status done appointment.save() messages.success(request, 病历已保存) return redirect(doctor_home) return render(request, medical_records/write.html, {appointment: appointment})不要在图省事的时候直接写request.user.is_doctor应该通过request.user.profile.doctor取到 Doctor 对象再和挂号的 doctor 对比。这样才能确保不仅是“医生角色”而且是对应那位医生。4.5 用 Admin 后台管理基础数据Django Admin 是本项目白送的管理后台。只需要在admin.py里做简单注册# departments/admin.py from django.contrib import admin from .models import Department, Doctor admin.site.register(Department) admin.site.register(Doctor)然后通过/admin登录就可以维护科室、医生、患者的增删改查不写一行 HTML。真实项目里医院信息管理系统的“基础数据维护”配置维护岗多半就直接用 Admin 系统来做这个设计思路是从 Django 社区里一路实践出来的。5. 常见问题与坑点排查这一节算是全篇最值钱的干货基本是我自己从头写这类系统时踩过一遍的坑一个一个说清楚。5.1 时区和日期问题导致的时间差 8 小时现象查出来的挂号日期和本地差了 8 个小时。原因USE_TZ True时Django 在内存中统一使用 UTC 时间只有渲染模板或者调用localtime才转成本地时间。如果直接在 Python 里用datetime.now()拿当前时间拿到的是本地时间和 UTC 混在一起就会乱。正确姿势在视图里取“今天”要使用from django.utils import timezone today timezone.localdate()取当前时间用now timezone.now()不要在业务代码里直接 importdatetime.now()除非这个值只是当作一个普通的字符串去展示。5.2 N1 查询的性能陷阱现象在医生列表页面显示每个医生对应的科室名称时页面加载极其慢SQLite 可能看不出切到 MySQL 后立刻暴露。原因模板里做了这样的循环{% for doctor in doctors %} {{ doctor.department.name }} {% endfor %}每渲染一个医生Django ORM 就额外执行一次查询去取 department这属于典型的 N1 查询。如果医生有 500 条就会执行 501 条 SQL。解决办法是在视图中用select_related()预取外键关联doctors Doctor.objects.select_related(department).all()select_related适用于一对一和多对一它会把关联表 JOIN 在一起一次查出。多对多场景要改用prefetch_related比如“查询所有患者并预取他们的挂号记录”。5.3 CSRF 验证失败 403现象POST 表单提交后页面报 403 Forbidden。原因Django 默认开启 CSRF 防护页面的 form 里必须带上{% csrf_token %}模板标签生成一个随机 token 并在后端验证。解决办法模板里的每一个 form 都要加form methodpost {% csrf_token %} ... /form如果你做 API 接口并关闭了 CSRF是在as_view()上直接对视图加csrf_exempt装饰器但这种操作要确认你明确知道自己关闭了什么否则等于把安全门拆了。5.4 迁移报警告Changes that will not be applied现象执行makemigrations后提示类似It is impossible to add a non-nullable field xxx to ...原因你给已存在的表添加了一个不允许为空、又没有默认值的字段。Django 不知道该怎么给已有数据填这个字段所以拒绝生成正常的迁移。遇到这种问题最简单的办法是给字段设置默认值或允许为空title models.CharField(max_length50, blankTrue, default)如果是已经上线有生产数据的系统处理方式就要做“数据迁移脚本”但新手阶段一般不会遇到这层压力。5.5 一对多删除造成的数据丢失现象删除一个科室结果系统提示关联的医生、挂号记录也被删了。原因外键默认on_deletemodels.CASCADE。正确姿势对“医师科室删除”这种基础数据用PROTECT保护住。对“患者删号挂号记录跟着删”这种业务可以用CASCADE因为这是符合直觉的。模块之间要有意识地决定哪些关系是保护性的、哪些是级联的不要一顺手全用默认。5.6 静态文件 404 和部署前的配置开发环境访问/static/xxx.css404或者正常但图片加载不出来。开发时要在settings.py打开静态文件STATIC_URL /static/ STATICFILES_DIRS [ BASE_DIR / static, ]部署到正式服务器时还要执行python manage.py collectstatic这个命令会把所有 App 的静态文件集中拷贝到STATIC_ROOT目录然后再交给 Nginx 这类 Web 服务器托管。很多人不知道这步生产环境上线后页面就裸奔了。5.7 使用模型表单减少表单验证代码与其手写一大堆if request.POST[field]判断不如直接用 Django Form 生成表单和做校验。以患者注册为例from django import forms class PatientRegisterForm(forms.ModelForm): class Meta: model UserProfile fields [username, password, real_name, phone, role] widgets { password: forms.PasswordInput(), }这个 Form 既可以渲染 HTML又自动把字段类型、必填性、最大长度这些约束映射成前端校验和后台校验代码量和出错率都会降下来。工程化程度越高越应该用这套而不是每个字段手写一遍。6. 最后再分享一点我对这类项目的心得做医院信息管理系统这类偏“业务型”的 Django 项目最有价值的收获不是“学会了某一套框架”而是建立起一套完整的业务建模和工程思维。你要学会面对一个需求去拆表、拆字段、定状态、设定外键约束你要懂得给核心操作加上事务和并发控制你要理解 Django 自带的认证、Admin、ORM 这些模块在真实系统里怎么配合使用。我还记得我第一次做这个系统的时候最大的坑反而不是代码是在代办事项里花了太多时间纠结“要不要上 Redis 做缓存”“要不要上 JWT 做认证”“要不要弄前后端分离”。这些技术本身没问题但对这个体量的项目来说都是过度设计。先把 Django 模板、Session 认证、ORM 和业务逻辑做好等真的有并发压力和前后端分离需求了再去做架构升级才是正路。如果你也想动手做我建议按这个次序来先把模型设计完整把 Admin 后台配上并录入几组测试数据然后实现登录注册和角色跳转再做挂号和病历闭环最后再补前端样式和统计报表。每完成一个环节你能看到系统真实地在运转成就感会推着你继续往下走。等这几个模块都跑通了后续扩展方向也很明确可以做图表统计比如用 ECharts 展示各科室门诊量可以接消息通知挂号成功后发短信或邮件可以把 Django 升级成 DRF 输出 JSON 接口给小程序端。这套地基打底打得好往上盖什么楼层都不慌。最后再提一个小技巧开发过程中每写完一个模块马上用git commit打个快照。这样你后期调整模型、改数据库字段时出了问题可以随时回滚比什么都强。希望你也能把这个项目完整做出来做完你会发现自己的编程能力比刚上手时有了肉眼可见的进步。
网站建设高端定制企业官网