1. 项目概述
这个基于Python和Django框架开发的智能租房推荐系统,是我在完成计算机专业毕业设计时的一个实战项目。作为一个经常需要租房的城市打工人,我深刻体会到在海量房源信息中寻找合适住所的痛苦——要么信息过载无从下手,要么筛选条件单一错过好房。这个系统正是为了解决这些痛点而设计的。
系统采用了前后端分离的架构模式,后端使用Django框架搭建RESTful API,前端采用HTML/CSS构建响应式界面,数据库选用MySQL存储房源和用户数据。最核心的创新点是融合了基于用户和基于物品的两种协同过滤推荐算法,能够根据用户的历史行为智能推荐可能感兴趣的房源。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构解析
2.1 后端技术栈
Django框架是这个项目的基石。选择Django而非Flask等轻量级框架,主要考虑到它自带的ORM、Admin后台和完整的MVT架构,特别适合快速开发数据密集型的Web应用。我在项目中主要使用了以下Django组件:
- Models:定义了User(用户)、House(房源)、Rating(评分)、Comment(评论)等核心数据模型
- Views:采用基于类的视图(CBV)处理各种业务逻辑
- Templates:虽然主要是前后端分离,但部分管理页面仍使用Django模板
- REST Framework:构建API接口供前端调用
数据库方面,MySQL 8.0提供了良好的性能和稳定性。我特别设计了以下优化:
python复制# 示例模型定义
class House(models.Model):
title = models.CharField(max_length=200)
price = models.IntegerField()
area = models.FloatField()
address = models.TextField()
tags = models.ManyToManyField('Tag')
# 添加数据库索引
class Meta:
indexes = [
models.Index(fields=['price']),
models.Index(fields=['area']),
]
2.2 前端实现
前端页面使用Bootstrap 5构建响应式布局,确保在手机和PC上都有良好的浏览体验。数据可视化部分采用了ECharts库,它提供了丰富的图表类型和灵活的配置选项。
关键的前端技术点包括:
- 使用AJAX实现无刷新交互
- 基于jQuery处理DOM操作和事件
- 自定义CSS实现房源卡片的hover效果
- 响应式设计适配不同屏幕尺寸
3. 核心功能实现
3.1 用户系统模块
用户模块采用了Django自带的认证系统,并进行了扩展:
python复制from django.contrib.auth.models import AbstractUser
class CustomUser(AbstractUser):
phone = models.CharField(max_length=20, blank=True)
avatar = models.ImageField(upload_to='avatars/', null=True, blank=True)
def get_recommendations(self):
# 获取推荐房源逻辑
pass
安全措施包括:
- 密码加密存储
- CSRF防护
- 登录失败次数限制
- 会话管理
3.2 房源展示与搜索
房源列表页实现了多种筛选和排序方式:
- 基础筛选:按价格区间、面积、房型等条件
- 高级搜索:支持关键词搜索和标签过滤
- 排序功能:可按价格、面积、评分、收藏数等排序
前端通过AJAX获取数据后动态渲染,避免了整页刷新:
javascript复制function loadHouses(page=1, filters={}) {
$.ajax({
url: '/api/houses/',
data: {...filters, page: page},
success: function(data) {
renderHouseList(data.results);
renderPagination(data.count);
}
});
}
3.3 协同过滤推荐算法
系统实现了两种推荐算法:
基于用户的协同过滤(UserCF)
python复制class UserCF:
def __init__(self, all_user):
self.all_user = all_user # 格式:{用户1: {房源1:评分, 房源2:评分}, ...}
def pearson(self, user1, user2):
# 计算皮尔逊相关系数
sum_xy = sum_x = sum_y = sumX2 = sumY2 = n = 0
for movie in user1:
if movie in user2:
n += 1
sum_xy += user1[movie] * user2[movie]
sum_x += user1[movie]
sum_y += user2[movie]
sumX2 += user1[movie]**2
sumY2 += user2[movie]**2
if n == 0: return 0
numerator = sum_xy - (sum_x * sum_y)/n
denominator = sqrt((sumX2 - sum_x**2/n) * (sumY2 - sum_y**2/n))
return numerator/denominator if denominator !=0 else 0
基于物品的协同过滤(ItemCF)
python复制def similarity(movie1_id, movie2_id):
# 计算两部房源的相似度
movie1_raters = Rate.objects.filter(movie_id=movie1_id).count()
movie2_raters = Rate.objects.filter(movie_id=movie2_id).count()
common = Rate.objects.filter(
movie_id=movie2_id,
user_id__in=Rate.objects.filter(movie_id=movie1_id).values('user_id')
).count()
return common / sqrt(movie1_raters * movie2_raters) if movie1_raters*movie2_raters!=0 else 0
实际应用中,两种算法各有优劣:
- UserCF更适合用户量大的场景
- ItemCF在房源数量稳定时效果更好
- 我们最终采用了加权混合的策略
4. 数据可视化实现
4.1 ECharts集成
系统使用ECharts实现了多种可视化图表:
- 租金分布图:展示不同价格区间的房源数量
- 词云图:显示热门小区和房源特征
- 发布时间趋势图:分析房源更新时间规律
- 饼图:展示各类房型的占比
前端初始化图表的典型代码:
javascript复制function initRentChart(data) {
var chart = echarts.init(document.getElementById('rent-chart'));
var option = {
title: { text: '租金分布' },
tooltip: {},
xAxis: { data: data.priceRanges },
yAxis: {},
series: [{
name: '数量',
type: 'bar',
data: data.counts
}]
};
chart.setOption(option);
}
4.2 数据处理
后端需要为图表提供格式化数据:
python复制def get_rent_distribution():
ranges = ['0-1000', '1001-2000', '2001-3000', '3001-4000', '4000+']
counts = [
House.objects.filter(price__lte=1000).count(),
House.objects.filter(price__range=(1001,2000)).count(),
# 其他区间...
]
return {'priceRanges': ranges, 'counts': counts}
5. 系统部署与优化
5.1 生产环境部署
项目最终部署在Ubuntu服务器上,采用Nginx+Gunicorn的方案:
- Nginx:处理静态文件和反向代理
- Gunicorn:作为WSGI服务器运行Django应用
- MySQL:单独部署在一台服务器上
- Redis:缓存热门数据和会话信息
部署步骤摘要:
bash复制# 安装依赖
pip install -r requirements.txt
# 收集静态文件
python manage.py collectstatic
# 启动Gunicorn
gunicorn --workers 4 --bind unix:recommend.sock recommend.wsgi:application
5.2 性能优化
针对系统瓶颈做了以下优化:
-
数据库优化:
- 添加适当的索引
- 使用select_related和prefetch_related减少查询次数
- 对大数据表进行分表
-
缓存策略:
- 使用Redis缓存热门房源数据
- 实现推荐结果的缓存
- 页面片段缓存
-
前端优化:
- 静态资源CDN加速
- 图片懒加载
- 减少HTTP请求
6. 开发经验与教训
在开发这个系统的过程中,我积累了一些宝贵的经验:
-
数据质量至关重要:初期使用的测试数据质量较差,导致推荐结果不准确。后来通过爬取真实租房数据并人工清洗,效果显著提升。
-
算法参数调优:协同过滤算法中的相似度阈值、近邻数量等参数需要反复调试。最终通过A/B测试确定了最优参数组合。
-
用户体验细节:
- 搜索结果添加了"猜你喜欢"的推荐
- 收藏功能增加了二次确认防止误操作
- 评分系统采用五星级而非简单的数字输入
-
遇到的坑与解决方案:
- 问题:推荐结果有时会出现热门房源过度集中
- 解决:在算法中加入了流行度惩罚因子
- 问题:新用户冷启动问题
- 解决:对于新用户,先基于房源热度推荐,随着行为数据积累再转向个性化推荐
这个项目从技术选型到最终部署上线,整个过程让我对Web全栈开发有了更深入的理解。特别是推荐算法的实现和优化,让我认识到理论算法与实际应用之间的差距。未来还计划加入更多机器学习算法,并优化移动端体验。
