做毕设选题的时候,看到“基于Django的学生宿舍管理系统”这个题目,第一反应是“太普通了”。但真把这个项目从零到一完整做完,我才发现这类看似平平无奇的系统,恰恰是Django入门到进阶最扎实的练手项目,也是答辩时最容易讲清楚、最有话说的选题类型。这篇文章把我的完整设计思路、数据库建模、关键功能实现、踩坑记录和答辩准备经验全部整理出来,希望能帮到正在纠结选题或者已经选了类似题目的你。
先说清楚这个项目是什么:一套基于Django框架的学生宿舍管理系统,覆盖学生信息管理、宿舍分配、调宿退宿、访客登记、报修管理、公告发布等宿舍管理的核心场景,目标是让宿管员和辅导员从纸质台账里解放出来,用一套Web系统完成日常管理。系统采用Django的MTV架构,前端搭配Bootstrap,数据库用MySQL,整套代码结构清晰、注释完整,非常适合作为计算机科学与技术、软件工程等专业的毕业设计项目。
它适合谁来参考?如果你正在做Django相关的毕设,或者想用一套完整项目熟悉Django全流程开发——从模型设计到视图编写,从模板渲染到部署调试——这篇文章值得你花十分钟读完。我会把项目中真正核心的部分拆开讲,包括数据模型怎么设计才不会被后期需求改崩、宿舍分配规则怎么用代码表达、远程调试时那些让人抓狂的问题到底怎么排查。
1. 整体设计与思路拆解
1.1 为什么选Django做宿舍管理系统
宿舍管理系统本质是一个典型的CRUD系统:对宿舍资源、学生信息、报修工单、访客记录做增删改查。这种业务场景对框架的要求非常明确:ORM要顺手、Admin后台要强大、表单处理要省心,还得有成熟的用户认证体系。Django在这几点上几乎是无缝贴合。
对比其他方案,Spring Boot虽然企业级应用多,但Java体系对新手来说环境配置成本高,写一个分页查询都要堆一堆注解,对毕设时间周期来说性价比低。Flask轻量灵活,但用户认证、Admin后台、ORM都要自己组装,一个宿舍管理系统做下来,杂七杂八的依赖装了一堆,反而比直接用Django更绕。PHP的话,说实话现代毕设里再用原生PHP写管理系统,在答辩时很难讲出技术亮点。Django自带的django.contrib.auth用户认证、django.contrib.admin后台管理、ORM数据迁移机制,单独拎出来任何一个都够写进文档的“技术选型依据”,这种“自带轮子”的特性让开发者能把精力集中在业务逻辑本身。
还有一个被很多人忽略的点:Django的MTV模式对毕设文档撰写极其友好。三层结构在需求分析阶段就能对应上——Model对应数据层设计,Template对应前端页面,View对应业务逻辑,画系统架构图的时候结构清晰得可以直接截图放进论文。答辩时被问到“系统架构是什么样”,你掏出这张图就能讲清楚请求是怎么从浏览器流到数据库、再流回来的。
1.2 核心需求拆解:管理系统的关键角色与业务流程
设计宿舍管理系统之前,先要理解宿舍管理的真实场景。我走访过学校宿管办公室,观察了一线宿管员的工作日常,发现他们的核心痛点集中在几个地方:纸质登记本上查一个学生的住宿信息要翻半天,调宿流程靠手写申请单层层审批,报修电话一个接一个却没有工单跟踪,访客进出只在门卫那里登记个名字完全不可追溯。这些痛点映射到系统里就是四大核心模块:信息管理、宿舍分配与调宿、报修工单流转、访客安全管理。
角色设计上,我划分了三类用户:系统管理员(通常是学工处老师)、宿管员(楼栋管理员)、学生。三类角色的权限边界必须清晰:管理员管全局配置,比如楼栋信息、宿舍类型、床位数量;宿管员管日常业务,比如办理入住、处理报修、登记访客;学生只能看自己的住宿信息、提交报修申请、查看公告。这个权限设计直接决定系统的安全基线,如果学生能修改自己的宿舍号,整个系统就崩了。
在功能边界上,毕设项目最忌讳“什么都想做”。我当时列了一个功能清单,严格区分了“必须有”“可以有”“不要有”三档。必须有的是:登录认证、学生管理、宿舍管理、入住分配、报修管理、公告管理。可以有的是:访客登记、调宿申请、数据分析看板。不要有的是:在线缴费、智能门禁对接、消息推送,这些涉及硬件对接或第三方支付,复杂度高还容易出安全问题,对毕设来说纯粹是给自己挖坑。
1.3 架构设计与技术栈的完整清单
这套系统的架构可以用一句话概括:Django 3.2 + MySQL 8.0 + Bootstrap 5,前端模板渲染为主,少量jQuery做交互。不搞前后端分离,是因为宿舍管理系统页面多在服务器端渲染更简单,而且答辩时“Django模板引擎”本身就是一个可以讲半天的知识点,何必去把前端框架的复杂概念塞进来。
关键依赖清单如下:
- Django 3.2 LTS:LTS版本意味着长期支持,社区问题多、资料全,踩坑了容易搜到答案。
- MySQL 8.0:主流关系型数据库,支持事务和复杂查询,比SQLite更接近真实项目环境。
- django-crispy-forms:表单样式渲染利器,避免手写一大串Bootstrap表单类名。
- django-simple-captcha:登录验证码,防止暴力破解,也是文档里“安全性设计”的素材。
- Bootstrap 5 CDN:零构建步骤的CSS框架,省去前端工程化的全部烦恼。
这套技术栈没有超过毕设难度的任何东西,但每一层都有值得写进文档的内容。MySQL为什么不用SQLite?因为SQLite的文件型数据库没法体现“数据库设计”这门课学到的事务、锁、并发控制这些概念,答辩时老师一问“你这个系统并发能力怎么样”,用SQLite你只能沉默。换MySQL后至少能理直气壮地说:“生产环境用的就是关系型数据库,支持ACID事务。”
2. 核心细节解析与实操要点
2.1 数据库建模:5张核心表的字段与关系设计
数据库是管理系统的地基,地基歪了后面盖什么都塌。这套系统里最核心的数据表我拆成了五张:用户表、学生信息表、宿舍楼表、宿舍房间表、报修工单表,再加一张访客记录表作为扩展。表之间的关系用Django的ForeignKey和OneToOneField来表达。
先看用户表,这里有个关键设计决策:不扩展Django自带的User模型,而是单独建一张学生信息表用OneToOne关联User。原因很简单——扩展User表会导致Django Admin的认证流程变得复杂,而单独建表意味着学生专属字段(学号、班级、入住状态)都集中在一个逻辑清晰的地方,将来就算系统要接入其他登录方式也不受影响。这是一条Django社区的黄金实践,写进文档里就是亮点。
学生信息表的核心字段包括:学号(唯一索引)、姓名、性别、班级、联系电话、宿舍房间外键、入住状态(在住/退宿/调宿中)。注意学号一定要加unique=True,这是数据的天然唯一标识,比自增主键更可靠。
宿舍楼和宿舍房间的设计要分层:一栋楼有多层,每层有多个房间,每个房间有固定床位数量。我用了两张表:DormBuilding存楼栋名称、楼层数、地址;DormRoom存房间号、所属楼栋外键、房间类型(四人间/六人间)、当前入住人数、床位数。当前入住人数这个字段看起来冗余,但它是宿舍分配时判断“有没有空床位”的关键,如果临时去查入住学生表再统计人数,每次分配都是一个子查询,性能不经打不说,代码也啰嗦。
报修工单表则完全围绕状态机来设计:字段包括学生外键、宿舍房间外键、报修描述、报修类型(水/电/家具/网络)、状态(待处理/处理中/已完成)、提交时间、处理人、处理备注。状态字段是工单系统的灵魂,整个系统的业务逻辑里有一大段都在处理这个状态流转。
2.2 宿舍分配算法:怎么用代码表达“有空床位才能分配”
宿舍分配是宿舍管理系统最核心的业务规则,看起来简单,实际写起来要考虑很多边界情况。最基础的需求是:选择一个房间,系统判断该房间当前入住人数是否小于床位数,如果小于则允许分配,同时入住人数加一;如果等于则提示“该宿舍已满”。
这个逻辑用Django的ORM写起来很简洁:
def assign_student_to_room(student, room_id): from django.db import transaction with transaction.atomic(): room = DormRoom.objects.select_for_update().get(id=room_id) if room.current_occupancy >= room.bed_capacity: raise ValidationError("该宿舍已满,请选择其他宿舍") room.current_occupancy += 1 room.save() student.room = room student.occupancy_status = 'in_room' student.save()这里有两个关键点值得展开讲。第一,select_for_update()配合transaction.atomic()是数据库行级锁,解决并发场景下“两个人同时看到最后一个床位然后都分配成功”的经典超卖问题。这个细节在答辩时是实打实的加分项,说明你考虑了并发安全。第二,把业务规则“已满不能分配”放在事务里而不是模板里判断,保证了无论从哪个入口提交,最终数据安全都由数据库层兜底。
调宿和退宿的逻辑本质上是在这个基础上做变体。调宿是两张表各减一和加一的操作,同样要用事务包裹;退宿则要额外校验学生是否有未完成的报修工单,如果有,提示先处理完再退宿,避免“人走了,水管还在漏”的烂账。
2.3 报修工单状态机:从创建到完成的闭环
报修工单的场景非常有真实感:学生提交报修,宿管员查看工单,联系维修师傅上门,处理完成后更新状态,学生对整个流程可见。我设计的状态机只有三个状态:待处理→处理中→已完成,再加一个“已驳回”分支。
状态流转的代码实现上,我用了一个简单的方式:在Model里定义状态选择枚举,在View层写一个transition_status方法,专门负责状态变更的合法性和日志记录。状态变更是需要记录时间线的,我在工单表里加了一个history的JSON字段,每次状态变化都往里面追加一条记录。这个JSON字段一开始觉得不正式,但实际用下来发现做数据审计追踪非常方便,而且写成文档就是一个“操作日志模块”的亮点。
2.4 用户认证与权限控制的关键细节
Django自带的认证体系已经覆盖了登录、Session管理、密码加密这些基础需求,但要结合宿舍管理系统做三角色权限控制,还需要用心设计一番。
核心要点是:用Group而不是用Permission单点绑定。我在系统初始化时创建三个Group:admin、dorm_manager、student,每个Group配置对应的权限集合,用户归属到某个Group就自动继承相关权限。这种设计的好处是权限配置与业务解耦,新增一个角色时只需要创建新的Group,不需要在代码里堆if user.is_student之类的判断分散在各处。
视图层的权限控制我统一用@user_passes_test装饰器做二次拦截,模板层再用{% if user.is_authenticated %}控制菜单渲染。为什么两层都要?因为模板层只解决“看起来有没有入口”,视图层才是真正的安全边界,隐藏入口永远不能替代后端校验。
3. 实操过程与关键功能实现
3.1 从零初始化项目:环境搭建与项目结构规划
我习惯把环境搭建步骤写得清清楚楚,因为这一步卡住的新手最多。具体操作如下:
# 创建虚拟环境并激活 python -m venv venv source venv/bin/activate # Windows下用 venv\Scripts\activate # 安装依赖 pip install django==3.2 mysqlclient django-crispy-forms django-simple-captcha # 创建项目与两个应用:accounts负责认证与用户资料,dorm负责宿舍业务 django-admin startproject dormitory_system cd dormitory_system python manage.py startapp accounts python manage.py startapp dorm项目结构规划上,我的建议是:账号相关功能放accounts,宿舍业务放dorm,这种划分让每个应用的职责清晰,将来扩展时不会把代码搅成一锅粥。settings.py里要配置MySQL连接信息,要注意mysqlclient在Windows上安装容易报错,建议提前装好Microsoft C++ Build Tools或者直接用pymysql顶替,另外别忘了在__init__.py里加一行:
import pymysql pymysql.install_as_MySQLdb()3.2 关键代码实现:登录、查询与宿舍分配
登录页用了django.contrib.auth的authenticate和login,加上django-simple-captcha的验证码校验。核心逻辑不长,但每个细节都有讲究:
from django.contrib.auth import authenticate, login from django.contrib.auth.decorators import login_required from django.shortcuts import render, redirect from .forms import CaptchaLoginForm def user_login(request): if request.method == 'POST': form = CaptchaLoginForm(request.POST) if form.is_valid(): username = form.cleaned_data['username'] password = form.cleaned_data['password'] user = authenticate(request, username=username, password=password) if user is not None: login(request, user) if user.groups.filter(name='dorm_manager').exists(): return redirect('dashboard_manager') return redirect('dashboard_student') else: form.add_error(None, '用户名或密码错误') else: form = CaptchaLoginForm() return render(request, 'accounts/login.html', {'form': form})这里一个容易被忽略的点是:authenticate只能验证用户名和密码,验证码的校验在form.is_valid()里就已经完成了。也就是说,验证码错了根本不会进入用户校验环节,这从用户流程上是很合理的——先证明你是人,再证明你是你。
宿舍列表查询我用了Django ORM的select_related来减少联表查询次数:
rooms = DormRoom.objects.select_related('building').annotate( available_beds=F('bed_capacity') - F('current_occupancy') ).filter(available_beds__gt=0)annotate里用F表达式做的这个差值计算非常关键,它把“可用床位”这个动态概念变成了一个可筛选的字段,效率上远高于取所有房间后在Python里算。而且这里用F表达式而不是直接读Python属性,意味着这个计算是发生在数据库层面的,查询性能至少差一个数量级。
宿舍分配功能的视图前面已经在“核心细节”章节写过代码,这里重点补充模板层的交互。分配页面的核心是:选择学生、选择宿舍楼、选择具体房间,三个步骤联动。我做了两个关于Ajax的接口,一个根据楼栋ID返回该楼栋下的房间列表(过滤当前入住数小于容量的房间),另一个根据房间ID返回房间详情和入住学生列表。用jQuery的$.getJSON就能实现,不引入Vue这些前端框架,保持简单。
3.3 远程调试与联调:一个必须掌握的实操技能
毕设项目出现“在我电脑上能跑,在你电脑上不行”的经典问题几乎不可避免,这时候远程调试的能力就非常重要了。这里的远程调试分两种情况:一种是别人帮你查代码问题,需要让你运行一个带调试信息的版本;另一种是你在答辩现场,需要用另一台机器打开项目演示。
最简单的做法是使用Django自带的runserver配合--insecure参数,通过内网穿透工具把本地服务暴露出去。注意,仅限在明确的调试场景使用,不要在公网环境长期运行。
另外一个更稳的方案是把项目推到代码托管平台,在另一台机器上克隆后创建虚拟环境安装依赖,用python manage.py migrate初始化数据库,再runserver跑起来。这个过程看起来繁琐,但正是“环境一致性”的核心实践。为了确保这一步顺利,我强烈建议一开始就写一份完整的requirements.txt,并且固定版本号,比如Django==3.2.18而不是Django>=3.2。版本不锁死,换台机器很可能会拉到不兼容的新版本,到时候哭都来不及。
远程调试阶段我踩过最大的坑是MySQL连接不上。原因排查了很久,最后发现是MySQL 8.0默认的认证插件是caching_sha2_password,而mysqlclient版本太老不兼容。解决办法是创建用户时指定认证插件:
CREATE USER 'dorm_user'@'%' IDENTIFIED WITH mysql_native_password BY 'your_password'; GRANT ALL PRIVILEGES ON dormitory_db.* TO 'dorm_user'@'%'; FLUSH PRIVILEGES;这类问题在答辩演示时特别容易暴露,事前把环境问题全部解决,现场才能行云流水。
3.4 管理后台配置:用Django Admin省掉一半体力活
Django Admin是这套系统里被低估的一块价值。宿舍管理系统的数据录入工作,比如导入学生名单、录入楼栋信息、维护房间类型,如果在自定义页面里做,工作量巨大。但通过配置Admin,几乎不写代码就能完成。
我在dorm/admin.py里做了三件事:注册模型、配置list_display展示关键列、添加list_filter和search_fields实现筛选搜索。举个例子:
from django.contrib import admin from .models import Student, DormRoom, RepairOrder @admin.register(DormRoom) class DormRoomAdmin(admin.ModelAdmin): list_display = ('room_number', 'building', 'room_type', 'bed_capacity', 'current_occupancy') list_filter = ('building', 'room_type') search_fields = ('room_number',)这十几行代码给宿管员带来的价值是:他们可以在后台直接按楼栋筛选宿舍、按房间号搜索学生、给报修工单改状态、管理公告内容。Admin后台就成了一个免费的、安全的管理端,自定义前端页面专注给学生用就好。这个思路在毕业论文里写“系统包含用户端和管理端双入口”,一点水分都没有。
4. 常见问题与排查技巧实录
4.1 开发期高频Bug与修复思路
开发这套系统前后我踩了不下二十个坑,挑几个最有代表性的分享。
第一个坑是关于ForeignKey查询时的DoesNotExist异常。当我写学生列表页,模板里使用{{ student.room.room_number }}来显示宿舍号时,如果一个没有分配宿舍的学生混进了列表,Django模板引擎会静默渲染空字符串,不报错。但在视图里执行student.room.building这种二级关联时,如果你没有做空值校验,直接抛RelatedObjectDoesNotExist异常,页面直接500。解决办法很简单:在视图中用select_related('room__building')做联表查询,并且在模板中用{% if student.room %}做判空。
第二个坑是模板里对QuerySet的重复评估。我一开始在视图里统计男女生数量、在住人数、待处理工单数,全是拿着students = Student.objects.all()这个查询集反复用filter,结果生成了大量重复SQL,页面响应慢得离谱。后来改成在视图里一次性用aggregate和Count聚合,页面响应时间从800ms降到80ms。这个优化点写进论文的“系统性能优化”章节非常加分。
第三个坑是表单提交时CSRF验证失败。如果你用了Django自带的模板渲染表单,必须要记得在<form>标签里加{% csrf_token %}。但如果你是用Ajax提交表单,需要先从cookie里读取csrftoken再放入请求头。我在这里踩坑是因为先写了Ajax提交,忘记处理CSRF Token,结果所有POST请求都返回403,排查了半小时才反应过来。
4.2 常见问题速查表
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 登录后跳转404 | LOGIN_REDIRECT_URL未配置 | 在settings.py设置LOGIN_REDIRECT_URL='/dashboard/' |
| 图片静态文件加载失败 | DEBUG=False时静态文件服务关闭 | 用whitenoise或配置STATIC_ROOT后collectstatic |
| 报修工单无法更新状态 | 视图中未通过@require_POST限制请求方法 | 配合@login_required确保安全和请求方法正确 |
| MySQL中文乱码 | 数据库字符集不是utf8mb4 | 创建数据库时指定CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci |
| 表单提交显示“该字段不能为空” | 浏览器端HTML5校验拦截 | 检查模板里是否有required属性,或使用novalidate绕过前端校验 |
| 远程调试时连接超时 | 内网穿透服务到期或带宽限制 | 检查穿透服务状态,换节点或降低页面资源体积 |
4.3 数据库安全与备份的日常操作
宿舍管理系统涉及学生隐私数据,安全不能只停留在“登录要有密码”这个层面。我在项目里额外做了两件事。
第一件事是数据备份脚本。用一个简单的Cron定期执行mysqldump,把数据库导出为SQL文件并压缩归档。写这段脚本用了不到二十行,但它是答辩时“系统维护与安全设计”章节的实打实素材。
#!/bin/bash BACKUP_DIR="/var/backups/dormitory" DATE=$(date +%Y%m%d_%H%M%S) mysqldump -u root -p****** dormitory_db | gzip > $BACKUP_DIR/dormitory_$DATE.sql.gz find $BACKUP_DIR -name "*.sql.gz" -mtime +30 -delete第二件事是对敏感字段加密。学生的手机号虽然在系统内部要给宿管员看,但从数据安全角度,如果数据库意外泄露,明文手机号就是灾难。我在Model的save方法里用Django内置的make_password做了简单的哈希处理,虽然这会让直接SQL查询看不到明文,但配合一个小工具函数在视图层解密,日常使用完全不受影响。这个设计在答辩时一提,老师就知道你对数据安全是有考量的。
4.4 从开发到部署:上线演示环境的最后一步
毕设答辩通常要现场演示系统,所以你需要一个能稳定运行的演示环境。我的建议是不要依赖自己的笔记本电脑,太容易被无线网络、电源、投影仪兼容性这些问题拖垮。租一台低配云服务器,装好Python 3.9、MySQL 8.0、Nginx,用gunicorn跑Django应用,然后把数据库跑通,整个系统24小时在线,答辩时只要打开浏览器输入网址就行。
部署的关键步骤和注意事项:
# 收集静态文件到指定目录 python manage.py collectstatic # 用gunicorn启动Django应用,绑在本机8000端口 gunicorn dormitory_system.wsgi:application --bind 127.0.0.1:8000 --workers 3 # Nginx配置反向代理,把80端口转发到8000 # 同时配置静态文件alias,/static/路径直接映射到STATIC_ROOT目录这里最容易出错的是collectstatic没执行或者Nginx的静态文件路径配错,导致页面样式全丢。一个稳妥的验证方法是:启动后直接浏览器访问服务器IP,先看首页能不能打开,再用“开发者工具”的Network面板看静态资源是否200。如果CSS没加载,八成是Nginx配置问题,重点检查alias路径和STATIC_ROOT是否一致。
另外一个部署时的坑是ALLOWED_HOSTS。在本地用localhost跑没问题,一旦部署到云服务器,settings.py里的ALLOWED_HOSTS必须加上服务器IP或域名,否则Django会直接拒绝请求,返回400。很多人部署完发现“页面打不开”,查了半天代码,其实只是少了这一行配置。
4.5 文档与答辩准备的实战建议
这套系统的代码量大约三千行左右,不算多,但论文文档写起来却很要功夫。我的核心建议是:论文结构跟着项目模块走,而不是按开发时间线走。本科毕业论文几乎有固定章节框架:绪论、需求分析、系统设计、系统实现、系统测试、总结与展望。我写系统设计时,把数据库E-R图、用例图、架构图全部画出来再填充文字;写系统实现时,每个模块配上核心代码片段和运行截图;写测试时,用一张表列出测试用例、预期结果、实际结果、结论。这些内容全是“实打实做过的事”,不需要编造。
答辩时老师大概率会追问几个问题,提前准备:
- 为什么用MySQL不用SQLite?答:并发能力、事务支持、更接近生产环境。
- 为什么宿舍分配要加
select_for_update?答:防止并发场景超分配。 - 你系统最大的安全风险是什么?答:学生隐私数据的泄露风险,所以做了加密和权限控制。
- 报修工单状态如何流转?答:用状态机模型,明确每个状态的合法跳转路径。
- 系统如何进行性能优化?答:
select_related减少查询次数、aggregate减少SQL执行、F表达式在数据库层计算。
这几个问题只要答得流畅,基本不会挂。
5. 扩展思路:这4个点让项目更上一个档次
如果你学有余力,希望让那个“普通”的宿舍管理系统变得更有竞争力,我建议你在以下四个方向选一个做深度扩展。
第一个方向是数据可视化。宿舍管理产生的数据天然适合做图表:各楼栋入住率、报修类型分布、维修响应时长趋势。用echarts在前端渲染图表,后端只需要提供JSON接口。这个扩展能让答辩时的系统演示环节瞬间提升一个档次,从“能用”变成“看着很专业”。
第二个方向是导入导出。批量导入学生名单是宿管员最痛的需求之一。用pandas读取Excel文件,校验学号唯一性、填充必要的默认字段,然后批量创建学生记录。导出的话,用openpyxl生成Excel报表。这个功能对实际使用价值极大,也是“系统易用性”的一个好佐证。
第三个方向是消息通知。报修工单状态变化时,如果宿管员能收到通知,整个流程的体验会好很多。实现方式可以是用django-celery-beat做定时任务扫描待办工单,配合邮件或站内通知推送。这里引入Celery能让论文写进“异步任务处理”技术点,含金量立刻不一样。
第四个方向是操作日志。前面提到的报修工单JSON字段可以扩展成全站的“操作审计日志”系统,用Django的middleware和signal记录关键操作:谁在什么时间修改了哪个学生的宿舍。答辩时讲“系统安全与可追溯性”,这一个扩展就撑起一整节内容。
我个人看法是:以上四个扩展最多选一个就够了,贪多嚼不烂。毕设考察的是完整度和深度,不是功能数量。
写在最后:这套系统教会我的几件事
做完这个项目,我最大的体会是:设计一个管理系统的难点从来不在写代码,而在于把真实世界的业务规则理清楚。宿舍分配要考虑并发、调宿要考虑状态一致性、报修工单要考虑全流程闭环,这些逻辑搬到任何其他管理系统里都是通用的。Django在这个过程中给我的支持非常扎实,它的ORM帮我挡掉了大量SQL细节,Admin后台让我少写了很多前端页面,认证体系让权限管理站在一个很高的起点上。
如果你正在做类似的项目,最后再分享一个小技巧:每天开发结束后,顺手把当天写的核心代码片段和相关文档截图保存到一个“素材文件夹”里。写论文和做答辩PPT的时候,你会无比感谢这个习惯。很多同学做完项目才发现PPT里没有架构图、没有运行截图、没有代码片段,只能重新跑起来截一遍图,浪费时间不说,演示环境还可能因为改动太多跑不起来了。项目代码本身是干巴巴的,但配上你当时的思考过程、踩坑记录,它就是一个可以被讲成精彩故事的完整项目了。