1. 项目概述
作为一名有多年Django开发经验的程序员,我最近完成了一个基于Django的学生宿舍管理系统。这个系统采用B/S架构,使用Python+Django作为后端框架,MySQL作为数据库,实现了宿舍管理的数字化和智能化。系统包含用户管理、宿舍分配、报修管理、访客登记等核心功能模块,能够满足高校宿舍管理的日常需求。
在实际开发过程中,我发现很多同学在做毕业设计时都会遇到类似的问题:如何选择合适的框架?如何设计数据库?如何实现前后端交互?这个项目正好可以作为Django入门和实战的典型案例。下面我将从技术选型、系统设计、功能实现等方面详细讲解这个项目的开发过程。
2. 技术选型与架构设计
2.1 技术栈选择
后端框架选择Django的原因:
- Django是Python最流行的全栈Web框架,自带ORM、模板引擎、路由等组件,开发效率高
- 内置Admin后台管理系统,可以快速搭建管理界面
- 完善的文档和活跃的社区,遇到问题容易找到解决方案
- 安全性高,内置CSRF、XSS等防护机制
- 适合中小型项目快速开发,符合学生宿舍管理系统的规模
数据库选择MySQL的考虑:
- 关系型数据库适合处理结构化数据,如学生信息、宿舍信息等
- MySQL性能稳定,社区版免费,适合学校场景
- 与Django的ORM兼容性好,配置简单
- 支持事务处理,保证数据一致性
前端技术选择:
- 使用Bootstrap作为UI框架,快速构建响应式界面
- 采用jQuery简化DOM操作和AJAX请求
- 使用ECharts实现数据可视化展示
2.2 系统架构设计
系统采用经典的MVC架构模式:
-
模型层(Model):
- 使用Django的ORM定义数据模型
- 包含Student(学生)、Dormitory(宿舍)、Repair(报修)等核心模型类
- 处理所有数据库操作和业务逻辑
-
视图层(View):
- 处理HTTP请求并返回响应
- 包含基于函数的视图和基于类的视图
- 实现权限控制、数据验证等中间件
-
模板层(Template):
- 使用Django模板语言渲染HTML页面
- 实现页面布局和组件复用
- 支持静态文件管理
系统架构图如下:
code复制客户端浏览器 → Django Web服务器 → MySQL数据库
↑ ↑
| |
(HTML/CSS/JS) (Python/Django)
3. 数据库设计
3.1 核心数据表设计
学生表(Student)
python复制class Student(models.Model):
student_id = models.CharField(max_length=20, unique=True) # 学号
name = models.CharField(max_length=50) # 姓名
gender = models.CharField(max_length=10) # 性别
college = models.CharField(max_length=100) # 学院
major = models.CharField(max_length=100) # 专业
grade = models.CharField(max_length=20) # 年级
phone = models.CharField(max_length=20) # 联系电话
email = models.EmailField() # 邮箱
status = models.IntegerField(default=1) # 状态(1:正常 0:禁用)
class Meta:
db_table = 'student'
宿舍表(Dormitory)
python复制class Dormitory(models.Model):
building = models.CharField(max_length=50) # 楼栋号
room_number = models.CharField(max_length=20) # 房间号
room_type = models.CharField(max_length=50) # 房间类型(4人间/6人间)
capacity = models.IntegerField() # 可住人数
current_count = models.IntegerField(default=0) # 当前人数
status = models.IntegerField(default=1) # 状态(1:可用 0:维修中)
class Meta:
db_table = 'dormitory'
unique_together = ('building', 'room_number') # 联合唯一约束
宿舍分配表(Allocation)
python复制class Allocation(models.Model):
student = models.ForeignKey(Student, on_delete=models.CASCADE)
dormitory = models.ForeignKey(Dormitory, on_delete=models.CASCADE)
bed_number = models.CharField(max_length=10) # 床位号
check_in_date = models.DateField() # 入住日期
check_out_date = models.DateField(null=True, blank=True) # 退宿日期
status = models.IntegerField(default=1) # 状态(1:在住 0:已退宿)
class Meta:
db_table = 'allocation'
报修表(Repair)
python复制class Repair(models.Model):
REPAIR_STATUS = (
(0, '待处理'),
(1, '处理中'),
(2, '已完成'),
(3, '已取消')
)
student = models.ForeignKey(Student, on_delete=models.CASCADE)
dormitory = models.ForeignKey(Dormitory, on_delete=models.CASCADE)
title = models.CharField(max_length=100) # 报修标题
description = models.TextField() # 报修描述
repair_type = models.CharField(max_length=50) # 报修类型
status = models.IntegerField(choices=REPAIR_STATUS, default=0) # 状态
create_time = models.DateTimeField(auto_now_add=True) # 创建时间
finish_time = models.DateTimeField(null=True, blank=True) # 完成时间
class Meta:
db_table = 'repair'
3.2 数据库关系设计
- 学生与宿舍是多对多关系,通过宿舍分配表建立关联
- 一个学生可以提交多个报修记录
- 一个宿舍可以关联多个报修记录
- 使用外键约束保证数据完整性
注意事项:
- 在设计模型时,要考虑字段的null和blank属性区别
- 对于状态字段,使用choices参数定义可选值
- 重要字段要设置唯一约束或联合唯一约束
- 外键关系要明确on_delete行为
4. 核心功能实现
4.1 用户认证模块
登录功能实现:
python复制from django.contrib.auth import authenticate, login
def user_login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return redirect('index')
else:
messages.error(request, '用户名或密码错误')
return render(request, 'login.html')
权限控制实现:
python复制from django.contrib.auth.decorators import login_required, permission_required
@login_required
def student_list(request):
# 需要登录才能访问的视图
@permission_required('dormitory.view_student')
def student_detail(request, pk):
# 需要特定权限才能访问的视图
4.2 宿舍分配模块
分配算法实现:
python复制def allocate_dormitory(student_id, preference=None):
"""
自动分配宿舍算法
:param student_id: 学生ID
:param preference: 偏好(楼栋、房间类型等)
:return: 分配结果
"""
student = Student.objects.get(pk=student_id)
# 查找符合条件的宿舍
dormitories = Dormitory.objects.filter(
status=1, # 可用状态
room_type=preference.get('room_type') if preference else None,
current_count__lt=F('capacity') # 当前人数小于容量
).order_by('building', 'room_number')
if not dormitories.exists():
raise Exception('没有可用宿舍')
# 选择第一个符合条件的宿舍
dormitory = dormitories.first()
# 分配床位(自动计算下一个可用床位)
bed_numbers = Allocation.objects.filter(
dormitory=dormitory,
status=1
).values_list('bed_number', flat=True)
all_beds = [str(i) for i in range(1, dormitory.capacity + 1)]
available_beds = list(set(all_beds) - set(bed_numbers))
if not available_beds:
raise Exception('宿舍已满')
bed_number = available_beds[0]
# 创建分配记录
allocation = Allocation.objects.create(
student=student,
dormitory=dormitory,
bed_number=bed_number,
check_in_date=timezone.now().date(),
status=1
)
# 更新宿舍当前人数
dormitory.current_count = F('current_count') + 1
dormitory.save()
return allocation
4.3 报修管理模块
报修流程实现:
python复制@login_required
def create_repair(request):
if request.method == 'POST':
form = RepairForm(request.POST)
if form.is_valid():
repair = form.save(commit=False)
repair.student = request.user.student
repair.dormitory = request.user.student.current_dormitory()
repair.save()
messages.success(request, '报修申请已提交')
return redirect('repair_list')
else:
form = RepairForm()
return render(request, 'repair/create.html', {'form': form})
def process_repair(request, pk):
repair = get_object_or_404(Repair, pk=pk)
if request.method == 'POST':
action = request.POST.get('action')
if action == 'start':
repair.status = 1 # 处理中
repair.save()
elif action == 'complete':
repair.status = 2 # 已完成
repair.finish_time = timezone.now()
repair.save()
elif action == 'cancel':
repair.status = 3 # 已取消
repair.save()
return redirect('repair_detail', pk=pk)
return render(request, 'repair/detail.html', {'repair': repair})
5. 系统部署与优化
5.1 生产环境部署
部署架构:
- Web服务器:Nginx + Gunicorn
- 数据库:MySQL
- 缓存:Redis
- 静态文件:CDN或Nginx直接服务
部署步骤:
- 安装依赖:
bash复制pip install -r requirements.txt
- 收集静态文件:
bash复制python manage.py collectstatic
- 配置Gunicorn:
ini复制[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=www-data
Group=www-data
WorkingDirectory=/path/to/project
ExecStart=/path/to/gunicorn --workers 3 --bind unix:/tmp/project.sock project.wsgi:application
[Install]
WantedBy=multi-user.target
- 配置Nginx:
nginx复制server {
listen 80;
server_name yourdomain.com;
location /static/ {
alias /path/to/static/files;
}
location / {
include proxy_params;
proxy_pass http://unix:/tmp/project.sock;
}
}
5.2 性能优化建议
-
数据库优化:
- 添加适当的索引
- 使用select_related和prefetch_related减少查询次数
- 考虑使用缓存减轻数据库压力
-
缓存策略:
- 使用Django缓存框架缓存频繁访问的数据
- 对静态内容设置适当的缓存头
- 考虑使用Redis作为缓存后端
-
前端优化:
- 压缩静态资源(JS/CSS)
- 使用懒加载图片
- 减少HTTP请求数量
-
异步任务:
- 使用Celery处理耗时任务(如发送邮件、生成报表等)
- 避免在请求-响应周期中执行耗时操作
6. 常见问题与解决方案
6.1 开发环境问题
问题1:Django连接MySQL报错
code复制django.db.utils.OperationalError: (2002, "Can't connect to MySQL server on 'localhost'")
解决方案:
- 确保MySQL服务已启动
- 检查settings.py中的数据库配置
- 安装Python的MySQL客户端:
pip install mysqlclient
问题2:迁移数据库时报错
code复制django.db.migrations.exceptions.InconsistentMigrationHistory
解决方案:
- 删除数据库中的所有表
- 删除migrations文件夹中的所有迁移文件(除了__init__.py)
- 重新执行makemigrations和migrate
6.2 功能实现问题
问题3:用户权限不生效
可能原因:
- 权限没有正确分配给用户或组
- 视图没有添加权限装饰器
- 用户没有登录
检查步骤:
- 确认用户是否属于有权限的组
- 检查视图是否使用了@permission_required装饰器
- 确保用户已登录(@login_required)
问题4:表单提交后数据不保存
可能原因:
- 表单验证失败但没有显示错误
- 模型保存时出错
- 事务回滚
调试方法:
- 在视图中打印form.errors查看验证错误
- 检查模型字段约束条件
- 使用try-except捕获保存时的异常
6.3 生产环境问题
问题5:静态文件404错误
解决方案:
- 确保DEBUG=False时正确配置了STATIC_ROOT
- 运行collectstatic命令收集静态文件
- 检查Nginx/Apache配置是否正确指向静态文件目录
问题6:性能瓶颈
排查方法:
- 使用Django Debug Toolbar分析SQL查询
- 检查慢查询日志优化数据库
- 考虑添加缓存层
- 对高并发接口考虑使用异步处理
7. 项目扩展与改进
7.1 功能扩展建议
-
微信小程序端:
- 开发配套小程序方便学生随时查询和报修
- 使用Django REST framework提供API接口
- 实现扫码报修、通知推送等功能
-
数据统计分析:
- 使用Pandas分析宿舍使用率
- 可视化展示各楼栋报修情况
- 生成月度/年度报表
-
智能设备对接:
- 对接门禁系统实现刷脸进门
- 对接电表系统监控用电情况
- 对接监控系统增强安全管理
7.2 代码优化方向
-
重构为微服务架构:
- 将系统拆分为用户服务、宿舍服务、报修服务等
- 使用Django Channels实现实时通知
- 引入消息队列解耦服务
-
增强测试覆盖:
- 添加单元测试和集成测试
- 使用Selenium实现UI自动化测试
- 设置CI/CD流程自动运行测试
-
文档完善:
- 使用Sphinx生成API文档
- 编写部署手册和运维指南
- 添加代码注释和模块说明
在实际开发过程中,我发现Django的Admin后台虽然方便,但对于复杂的业务场景可能需要定制。这时可以考虑使用第三方库如django-admin-tools或完全自己开发管理界面。另外,对于需要频繁交互的功能,可以考虑引入Vue.js等前端框架实现更好的用户体验。
这个项目从技术角度涵盖了Web开发的各个方面,包括数据库设计、业务逻辑实现、前后端交互、权限控制等,是一个很好的全栈开发学习案例。通过这个项目,我深刻体会到良好的系统设计和规范的编码习惯对项目维护的重要性。