1. 项目背景与需求分析
学生公寓管理系统是高校信息化建设的重要组成部分。作为一名计算机专业的学生,选择这个课题作为毕业设计既符合专业培养目标,又具有实际应用价值。这个系统需要解决传统纸质化管理中的诸多痛点:
- 学生住宿信息登记混乱,查询困难
- 水电费收缴效率低下,统计不准确
- 访客登记流程繁琐,安全隐患大
- 维修申报流转不畅,响应速度慢
我在实际调研中发现,很多高校仍在使用Excel表格管理公寓数据,这导致信息孤岛现象严重。一个完善的公寓管理系统应该实现以下核心功能:
- 学生信息管理(入住、调宿、退宿)
- 宿舍分配与床位管理
- 水电费计算与收缴
- 访客登记与门禁管理
- 维修申报与进度跟踪
- 数据统计与分析报表
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术选型与开发环境搭建
2.1 Python版本选择
经过对比测试,我最终选择Python 3.8作为开发版本。这个版本在稳定性和新特性之间取得了良好平衡,对第三方库的支持也最为完善。特别要注意的是,某些学校实验室可能还在使用Python 2.7,务必确认开发环境版本:
bash复制python --version
如果显示2.x版本,需要重新安装Python 3.8+。建议使用pyenv进行多版本管理:
bash复制# 安装pyenv
curl https://pyenv.run | bash
# 安装指定Python版本
pyenv install 3.8.12
# 设置全局版本
pyenv global 3.8.12
2.2 开发框架选择
Django和Flask是Python Web开发的两大主流框架。对于毕业设计级别的项目,我推荐使用Django,原因如下:
- 自带Admin后台,快速实现CRUD功能
- ORM完善,数据库操作简单
- 内置用户认证系统
- 文档丰富,社区活跃
安装命令:
bash复制pip install django==3.2.16
提示:建议使用虚拟环境隔离项目依赖,避免污染系统Python环境:
bash复制python -m venv venv source venv/bin/activate # Linux/Mac venv\Scripts\activate # Windows
2.3 数据库选型
考虑到毕业设计的复杂度和数据量,SQLite是最佳选择。它无需单独安装服务,适合单机部署。Django默认支持SQLite,只需在settings.py中配置:
python复制DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
如果项目需要处理更复杂的数据关系,可以迁移到MySQL:
python复制DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'dormitory',
'USER': 'root',
'PASSWORD': 'yourpassword',
'HOST': 'localhost',
'PORT': '3306',
}
}
3. 系统设计与模型构建
3.1 数据库ER图设计
核心实体包括:
- 学生(Student)
- 宿舍(Dormitory)
- 床位(Bed)
- 水电费(UtilityBill)
- 访客(Visitor)
- 维修单(Maintenance)
使用Django的models.py定义数据模型:
python复制from django.db import models
from django.contrib.auth.models import User
class Dormitory(models.Model):
building = models.CharField(max_length=20)
room_number = models.CharField(max_length=10)
capacity = models.IntegerField()
current_occupancy = models.IntegerField(default=0)
phone = models.CharField(max_length=15)
def __str__(self):
return f"{self.building}-{self.room_number}"
class Student(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
student_id = models.CharField(max_length=20, unique=True)
dormitory = models.ForeignKey(Dormitory, on_delete=models.SET_NULL, null=True)
bed_number = models.CharField(max_length=10)
college = models.CharField(max_length=50)
major = models.CharField(max_length=50)
enrollment_date = models.DateField()
def __str__(self):
return self.user.get_full_name()
3.2 管理员界面定制
Django Admin默认界面功能有限,需要进行深度定制:
- 创建admin.py:
python复制from django.contrib import admin
from .models import *
@admin.register(Student)
class StudentAdmin(admin.ModelAdmin):
list_display = ('student_id', 'user', 'dormitory', 'bed_number')
list_filter = ('dormitory__building', 'college')
search_fields = ('student_id', 'user__first_name', 'user__last_name')
raw_id_fields = ('user', 'dormitory')
fieldsets = (
(None, {
'fields': ('user', 'student_id', 'dormitory', 'bed_number')
}),
('Academic Info', {
'fields': ('college', 'major', 'enrollment_date'),
'classes': ('collapse',)
}),
)
- 添加批量操作功能:
python复制@admin.action(description='Mark selected students as graduated')
def make_graduated(modeladmin, request, queryset):
queryset.update(status='graduated')
class StudentAdmin(admin.ModelAdmin):
actions = [make_graduated]
4. 核心功能实现
4.1 宿舍分配算法
实现智能宿舍分配需要考虑多个因素:
- 同专业学生尽量集中
- 同年级学生优先分配
- 特殊需求学生单独处理
python复制def assign_dormitory(student_list):
# 按专业和年级分组
groups = {}
for student in student_list:
key = (student.major, student.enrollment_date.year)
if key not in groups:
groups[key] = []
groups[key].append(student)
# 获取可用宿舍
available_dorms = Dormitory.objects.filter(
current_occupancy__lt=F('capacity')
).order_by('building', 'room_number')
# 分配逻辑
for (major, year), students in groups.items():
dorm_index = 0
for student in students:
while dorm_index < len(available_dorms):
dorm = available_dorms[dorm_index]
if dorm.current_occupancy < dorm.capacity:
student.dormitory = dorm
student.bed_number = dorm.current_occupancy + 1
dorm.current_occupancy += 1
dorm.save()
student.save()
break
dorm_index += 1
4.2 水电费计算模块
水电费计算需要考虑:
- 基础用量免费额度
- 超额部分阶梯计价
- 假期特殊费率
python复制def calculate_utility_bill(dormitory, month):
# 获取水电表读数
electricity = ElectricityRecord.objects.get(
dormitory=dormitory,
month=month
)
water = WaterRecord.objects.get(
dormitory=dormitory,
month=month
)
# 计算电费
free_electricity = 20 * dormitory.current_occupancy # 每人20度免费
used_electricity = max(0, electricity.usage - free_electricity)
if used_electricity <= 100:
electricity_fee = used_electricity * 0.5
elif used_electricity <= 300:
electricity_fee = 50 + (used_electricity - 100) * 0.8
else:
electricity_fee = 210 + (used_electricity - 300) * 1.2
# 计算水费(类似逻辑)
...
# 创建账单
bill = UtilityBill.objects.create(
dormitory=dormitory,
month=month,
electricity_usage=electricity.usage,
electricity_fee=electricity_fee,
water_usage=water.usage,
water_fee=water_fee,
total_fee=electricity_fee + water_fee,
is_paid=False
)
return bill
5. 前端界面开发
5.1 使用Bootstrap快速搭建UI
虽然Django模板系统功能完善,但样式需要自行处理。Bootstrap是最佳选择:
- 基础模板base.html:
html复制<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% block title %}学生公寓管理系统{% endblock %}</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
{% block extra_css %}{% endblock %}
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
<div class="container">
<a class="navbar-brand" href="/">公寓管理系统</a>
<div class="collapse navbar-collapse">
<ul class="navbar-nav me-auto">
<li class="nav-item"><a class="nav-link" href="{% url 'student_list' %}">学生管理</a></li>
<li class="nav-item"><a class="nav-link" href="{% url 'dormitory_list' %}">宿舍管理</a></li>
<li class="nav-item"><a class="nav-link" href="{% url 'bill_list' %}">费用管理</a></li>
</ul>
<div class="d-flex">
{% if user.is_authenticated %}
<span class="navbar-text me-3">欢迎,{{ user.username }}</span>
<a href="{% url 'logout' %}" class="btn btn-outline-light">退出</a>
{% else %}
<a href="{% url 'login' %}" class="btn btn-outline-light">登录</a>
{% endif %}
</div>
</div>
</div>
</nav>
<div class="container mt-4">
{% block content %}{% endblock %}
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
{% block extra_js %}{% endblock %}
</body>
</html>
5.2 学生列表页面
使用Django的ListView和分页功能:
python复制# views.py
from django.views.generic import ListView
from .models import Student
class StudentListView(ListView):
model = Student
template_name = 'student_list.html'
context_object_name = 'students'
paginate_by = 20
def get_queryset(self):
queryset = super().get_queryset()
# 添加搜索过滤
search = self.request.GET.get('search')
if search:
queryset = queryset.filter(
Q(user__first_name__icontains=search) |
Q(user__last_name__icontains=search) |
Q(student_id__icontains=search)
)
return queryset.select_related('user', 'dormitory')
对应模板:
html复制{% extends 'base.html' %}
{% block title %}学生列表{% endblock %}
{% block content %}
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0">学生列表</h5>
<form class="d-flex" method="get">
<input class="form-control me-2" type="search" name="search"
placeholder="搜索姓名或学号" value="{{ request.GET.search }}">
<button class="btn btn-outline-primary" type="submit">搜索</button>
</form>
</div>
<div class="card-body">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>学号</th>
<th>姓名</th>
<th>宿舍</th>
<th>床位</th>
<th>学院</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for student in students %}
<tr>
<td>{{ student.student_id }}</td>
<td>{{ student.user.get_full_name }}</td>
<td>{{ student.dormitory|default:"未分配" }}</td>
<td>{{ student.bed_number|default:"-" }}</td>
<td>{{ student.college }}</td>
<td>
<a href="{% url 'student_detail' student.id %}"
class="btn btn-sm btn-outline-primary">详情</a>
</td>
</tr>
{% empty %}
<tr>
<td colspan="6" class="text-center">没有找到符合条件的学生</td>
</tr>
{% endfor %}
</tbody>
</table>
{% if is_paginated %}
<nav aria-label="Page navigation">
<ul class="pagination justify-content-center">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="?page=1{% if request.GET.search %}&search={{ request.GET.search }}{% endif %}">首页</a>
</li>
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.previous_page_number }}{% if request.GET.search %}&search={{ request.GET.search }}{% endif %}">上一页</a>
</li>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
<li class="page-item active"><span class="page-link">{{ num }}</span></li>
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
<li class="page-item">
<a class="page-link" href="?page={{ num }}{% if request.GET.search %}&search={{ request.GET.search }}{% endif %}">{{ num }}</a>
</li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.next_page_number }}{% if request.GET.search %}&search={{ request.GET.search }}{% endif %}">下一页</a>
</li>
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.paginator.num_pages }}{% if request.GET.search %}&search={{ request.GET.search }}{% endif %}">末页</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
</div>
</div>
{% endblock %}
6. 系统部署与测试
6.1 生产环境部署
毕业设计通常需要演示,建议使用以下部署方案:
- 本地开发环境:SQLite + Django开发服务器
- 演示环境:Docker容器化部署
- 正式环境:Nginx + Gunicorn + PostgreSQL
Docker部署示例:
dockerfile复制# Dockerfile
FROM python:3.8-slim
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
RUN python manage.py collectstatic --noinput
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "dormitory.wsgi"]
docker-compose.yml:
yaml复制version: '3'
services:
web:
build: .
ports:
- "8000:8000"
volumes:
- .:/app
environment:
- DJANGO_SETTINGS_MODULE=dormitory.settings
depends_on:
- db
db:
image: postgres:13
environment:
- POSTGRES_DB=dormitory
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
6.2 自动化测试
编写测试用例确保核心功能正常:
python复制from django.test import TestCase
from django.contrib.auth.models import User
from .models import Dormitory, Student
class StudentTestCase(TestCase):
def setUp(self):
self.user = User.objects.create_user(
username='testuser',
password='testpass123',
first_name='张',
last_name='三'
)
self.dorm = Dormitory.objects.create(
building='A',
room_number='101',
capacity=4,
phone='123456789'
)
def test_student_creation(self):
student = Student.objects.create(
user=self.user,
student_id='20230001',
dormitory=self.dorm,
bed_number='1',
college='计算机学院',
major='计算机科学与技术',
enrollment_date='2023-09-01'
)
self.assertEqual(student.user.get_full_name(), '张三')
self.assertEqual(self.dorm.current_occupancy, 1)
def test_dormitory_assignment(self):
# 测试宿舍分配逻辑
pass
运行测试:
bash复制python manage.py test
7. 毕设文档撰写要点
优秀的毕业设计不仅需要代码实现,还需要规范的文档。主要包含:
-
需求分析文档:
- 现状分析
- 功能需求
- 非功能需求
- 用例图
-
系统设计文档:
- 架构设计
- 数据库设计
- 界面设计
- 安全设计
-
测试文档:
- 测试用例
- 测试结果
- 性能分析
-
用户手册:
- 安装指南
- 使用说明
- 常见问题
-
答辩PPT:
- 项目背景
- 技术亮点
- 演示截图
- 未来展望
注意:文档写作要避免直接复制代码,应该用流程图、时序图等描述系统工作原理。使用专业的UML工具如StarUML或PlantUML绘制设计图。
8. 项目优化与扩展
基础功能实现后,可以考虑以下扩展方向提升项目质量:
-
微信小程序端:使用Django REST Framework开发API,配合微信小程序实现移动端管理
-
数据可视化:使用ECharts或D3.js展示宿舍入住率、费用收缴率等数据
-
智能预警:基于历史数据预测水电用量异常,提前发现设备故障
-
人脸识别门禁:集成OpenCV实现刷脸进出宿舍
-
物联网集成:连接智能电表、水表实现自动读数
实现REST API示例:
python复制# serializers.py
from rest_framework import serializers
from .models import Dormitory
class DormitorySerializer(serializers.ModelSerializer):
class Meta:
model = Dormitory
fields = ['id', 'building', 'room_number', 'capacity', 'current_occupancy']
# views.py
from rest_framework import generics
from .serializers import DormitorySerializer
class DormitoryListAPIView(generics.ListCreateAPIView):
queryset = Dormitory.objects.all()
serializer_class = DormitorySerializer
class DormitoryDetailAPIView(generics.RetrieveUpdateDestroyAPIView):
queryset = Dormitory.objects.all()
serializer_class = DormitorySerializer
9. 常见问题与解决方案
在实际开发中遇到的一些典型问题及解决方法:
-
Django Admin中文显示问题:
在settings.py中添加:python复制LANGUAGE_CODE = 'zh-hans' TIME_ZONE = 'Asia/Shanghai' -
静态文件加载失败:
确保配置正确:python复制STATIC_URL = '/static/' STATIC_ROOT = BASE_DIR / 'staticfiles' STATICFILES_DIRS = [BASE_DIR / 'static']开发环境还需在urls.py中添加:
python复制from django.conf import settings from django.conf.urls.static import static urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) -
数据库迁移冲突:
当出现迁移冲突时,可以:bash复制rm -rf migrations/ python manage.py makemigrations your_app python manage.py migrate --fake -
性能优化技巧:
- 使用
select_related和prefetch_related减少数据库查询 - 对频繁访问的数据添加缓存
- 使用分页避免加载过多数据
- 使用
-
跨域问题解决:
安装django-cors-headers:bash复制
pip install django-cors-headers配置settings.py:
python复制INSTALLED_APPS = [ ..., 'corsheaders', ] MIDDLEWARE = [ ..., 'corsheaders.middleware.CorsMiddleware', ] CORS_ALLOW_ALL_ORIGINS = True # 开发环境可用,生产环境应限制
10. 项目总结与经验分享
通过这个项目的开发,我深刻体会到理论知识与实践结合的重要性。几点特别值得分享的经验:
-
需求分析要彻底:前期与"客户"(指导老师)充分沟通,明确每个功能的边界条件,避免后期频繁修改。
-
版本控制必不可少:使用Git管理代码,每次实现一个小功能就提交一次,方便回溯和协作。
-
测试驱动开发:先写测试用例再实现功能,虽然初期进度慢,但后期调试时间大大减少。
-
文档同步更新:代码修改后立即更新相关文档,避免最后统一整理时遗漏细节。
-
性能考量:即使数据量不大,也要考虑SQL查询效率,养成良好的数据库操作习惯。
对于学弟学妹们的建议:毕业设计选题要量力而行,选择既有挑战性又能完成的题目。Python+Django确实是个不错的选择,社区资源丰富,遇到问题容易找到解决方案。最重要的是保持编码习惯,每天都要有进度,避免最后突击。
