1. 项目概述
这个美食推荐系统是我在计算机专业毕业设计期间完成的一个实战项目,它融合了Python后端开发、Vue前端框架、MySQL数据库和协同过滤推荐算法等多项技术。系统不仅能展示美食信息,还能根据用户历史行为进行个性化推荐,并通过数据可视化大屏直观呈现美食数据的分布特征。
作为一个完整的Web应用,系统分为前台用户界面和后台管理界面两大部分。前台面向普通用户,提供美食浏览、搜索、评分、收藏、评论等功能;后台则供管理员进行数据管理和统计分析。整个项目采用Django作为后端框架,Vue.js构建前端交互界面,Echarts实现数据可视化,MySQL存储业务数据。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构设计
2.1 后端技术选型
后端采用Python+Django的组合,主要基于以下考虑:
- 开发效率:Django作为"全栈式"框架,内置ORM、模板引擎、路由管理等组件,可以快速构建功能完善的Web应用
- 扩展性:Django的MTV架构清晰,便于功能模块的扩展和维护
- 生态丰富:Python在数据处理和机器学习领域有丰富库支持,方便实现推荐算法
数据库选用MySQL 5.7版本,主要考虑因素包括:
- 成熟稳定,社区支持完善
- 满足关系型数据存储需求
- 与Django ORM无缝集成
2.2 前端技术方案
前端采用Vue.js框架,主要优势在于:
- 组件化开发,提高代码复用率
- 响应式数据绑定,简化DOM操作
- 丰富的第三方库支持(如Element UI)
数据可视化使用Echarts库,它能提供:
- 多种图表类型(柱状图、饼图、折线图等)
- 丰富的配置选项和交互功能
- 良好的浏览器兼容性
3. 核心功能实现
3.1 推荐算法实现
系统采用基于用户的协同过滤算法(UserCF),主要实现逻辑如下:
- 数据收集:记录用户对美食的评分(1-5星)
- 用户相似度计算:使用余弦相似度算法找出兴趣相似的用户
- 推荐生成:根据相似用户的评分预测目标用户可能喜欢的美食
核心代码实现:
python复制def calculate_user_similarity(user1, user2):
# 获取两个用户共同评分过的美食
common_items = set(user1.ratings.keys()) & set(user2.ratings.keys())
if not common_items:
return 0
# 计算余弦相似度
numerator = sum(user1.ratings[item] * user2.ratings[item] for item in common_items)
sum1 = sum(pow(user1.ratings[item], 2) for item in user1.ratings)
sum2 = sum(pow(user2.ratings[item], 2) for item in user2.ratings)
denominator = math.sqrt(sum1) * math.sqrt(sum2)
return numerator / denominator if denominator != 0 else 0
3.2 数据可视化实现
系统通过Echarts实现了多种数据可视化图表:
- 美食类型分布:饼图展示不同类型美食的占比
- 评分区间分布:柱状图展示不同评分区间的美食数量
- 热门美食排行:横向柱状图展示收藏量/评分最高的美食
关键配置示例:
javascript复制// 美食类型分布饼图配置
const typeChartOption = {
title: {
text: '美食类型分布',
left: 'center'
},
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b}: {c} ({d}%)'
},
series: [
{
name: '类型分布',
type: 'pie',
radius: ['40%', '70%'],
data: [
{value: 1048, name: '中式'},
{value: 735, name: '西式'},
{value: 580, name: '日式'},
{value: 484, name: '韩式'},
{value: 300, name: '其他'}
]
}
]
}
4. 数据库设计
系统主要数据表结构如下:
4.1 核心表设计
用户表(user)
sql复制CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`password` varchar(100) NOT NULL,
`name` varchar(50) DEFAULT NULL,
`role` varchar(20) DEFAULT 'USER',
`phone` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
美食表(food)
sql复制CREATE TABLE `food` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(100) NOT NULL,
`cover` varchar(255) DEFAULT NULL,
`score` decimal(3,1) DEFAULT '0.0',
`redu` int(11) DEFAULT '0',
`sc` int(11) DEFAULT '0',
`biaoqian` varchar(100) DEFAULT NULL,
`yuanliao` text,
`js` text,
`shijian` datetime DEFAULT NULL,
`type` varchar(50) DEFAULT NULL,
`category` varchar(50) DEFAULT NULL,
`fbr` varchar(50) DEFAULT NULL,
`fbrdetail` text,
`detail` text,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
4.2 关系表设计
评分表(rate)
sql复制CREATE TABLE `rate` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`score` int(11) NOT NULL,
`userid` int(11) NOT NULL,
`prodid` int(11) NOT NULL,
`time` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `userid` (`userid`),
KEY `prodid` (`prodid`),
CONSTRAINT `rate_ibfk_1` FOREIGN KEY (`userid`) REFERENCES `user` (`id`),
CONSTRAINT `rate_ibfk_2` FOREIGN KEY (`prodid`) REFERENCES `food` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
收藏表(collect)
sql复制CREATE TABLE `collect` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`userid` int(11) NOT NULL,
`prodid` int(11) NOT NULL,
`time` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `userid` (`userid`),
KEY `prodid` (`prodid`),
CONSTRAINT `collect_ibfk_1` FOREIGN KEY (`userid`) REFERENCES `user` (`id`),
CONSTRAINT `collect_ibfk_2` FOREIGN KEY (`prodid`) REFERENCES `food` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
5. 系统功能模块详解
5.1 用户模块
用户模块提供注册、登录、个人信息管理等功能:
-
注册流程:
- 输入用户名、密码、姓名、手机号
- 后端验证用户名唯一性
- 密码加密存储(使用Django内置的PBKDF2算法)
-
登录实现:
python复制def login(request):
if request.method == 'POST':
data = json.loads(request.body)
username = data['username']
password = data['password']
role = data['role']
if role == 'ADMIN':
user = Admin.objects.filter(username=username, password=password).first()
else:
user = User.objects.filter(username=username, password=password).first()
if user:
# 生成token并返回用户信息
token = generate_token(user.id)
return JsonResponse({
'code': 200,
'data': {
'token': token,
'userInfo': {
'id': user.id,
'username': user.username,
'name': user.name,
'role': user.role,
'phone': user.phone
}
}
})
else:
return JsonResponse({'code': 400, 'msg': '用户名或密码错误'})
5.2 美食展示模块
美食展示模块采用卡片式布局,支持以下功能:
- 分页加载:后端使用Django Paginator实现分页
- 搜索筛选:支持按美食名称和类型筛选
- 排序功能:可按评分、热度、收藏数排序
核心实现代码:
python复制def get_food_list(request):
page = request.GET.get('page', 1)
page_size = request.GET.get('page_size', 10)
search = request.GET.get('search', '')
food_type = request.GET.get('type', '')
sort = request.GET.get('sort', 'id')
queryset = Food.objects.all()
if search:
queryset = queryset.filter(title__icontains=search)
if food_type:
queryset = queryset.filter(type=food_type)
if sort in ['score', 'redu', 'sc']:
queryset = queryset.order_by(f'-{sort}')
paginator = Paginator(queryset, page_size)
page_obj = paginator.get_page(page)
data = [{
'id': item.id,
'title': item.title,
'cover': item.cover,
'score': float(item.score),
'type': item.type,
'category': item.category
} for item in page_obj]
return JsonResponse({
'code': 200,
'data': {
'list': data,
'total': paginator.count,
'page': page,
'page_size': page_size
}
})
6. 项目部署与优化
6.1 系统部署方案
项目采用Nginx+Django+MySQL的经典部署架构:
-
前端部署:
- Vue项目打包生成静态文件
- 配置Nginx作为静态文件服务器
-
后端部署:
- 使用Gunicorn作为WSGI服务器
- 配置Nginx反向代理到Gunicorn
-
数据库部署:
- MySQL单独部署在专用服务器
- 配置主从复制提高可用性
6.2 性能优化措施
-
数据库优化:
- 为常用查询字段添加索引
- 使用select_related/prefetch_related减少查询次数
- 配置数据库连接池
-
缓存策略:
- 使用Redis缓存热门美食数据
- 实现推荐结果缓存,减少重复计算
-
前端优化:
- 图片懒加载
- 组件按需加载
- 启用Gzip压缩
7. 开发经验与心得
7.1 技术难点与解决方案
-
冷启动问题:
- 问题:新用户没有评分记录,无法生成个性化推荐
- 解决方案:实现混合推荐策略,新用户随机推荐热门美食
-
数据稀疏性问题:
- 问题:用户评分数据稀疏,影响推荐准确性
- 解决方案:引入基于内容的推荐作为补充,结合美食类型、标签等信息
-
实时性要求:
- 问题:用户行为数据需要及时反映到推荐结果中
- 解决方案:设计增量更新机制,定期重新计算用户相似度
7.2 项目改进方向
-
算法优化:
- 尝试更多推荐算法(如矩阵分解、深度学习模型)
- 实现多算法融合的混合推荐系统
-
功能扩展:
- 添加社交功能,支持好友关注和美食分享
- 实现基于位置的附近美食推荐
-
性能提升:
- 引入分布式计算框架处理大规模数据
- 优化推荐算法计算效率
这个项目从需求分析到最终实现历时3个月,让我对Web全栈开发有了更深入的理解。最大的收获是学会了如何将理论知识应用到实际项目中,特别是在推荐算法实现过程中,通过不断调优和测试,最终达到了不错的推荐效果。
