基于Python的网上厨房美食推荐系统 - 技术分享博客
📋 目录
- 项目概述
- 技术栈
- 系统架构
- 核心功能实现
- 数据库设计
- 推荐算法
- 数据可视化
- 部署与优化
- 项目特色
- 总结与展望
🎯 项目概述
项目背景
随着生活节奏的加快,越来越多的人开始关注美食制作,但面对海量的菜谱信息,用户往往难以找到适合自己的菜谱。本项目旨在构建一个智能的美食推荐系统,通过个性化推荐算法,帮助用户快速找到心仪的菜谱。
项目目标
- 构建完整的菜谱管理和推荐系统
- 实现基于用户行为的个性化推荐
- 提供丰富的数据统计和可视化功能
- 支持用户社交互动功能
主要功能
- 🍳 菜谱管理:支持按类型和食材分类浏览菜谱
- ⭐ 智能推荐:基于协同过滤算法的个性化推荐
- 👥 用户系统:完整的用户注册、登录、个人中心功能
- 💬 社交互动:评论、收藏、关注等社交功能
- 📊 数据统计:丰富的统计分析和可视化展示
- 🔧 后台管理:完善的后台管理系统
项目源码
码界筑梦坊各大平台同名 欢迎咨询~
🛠️ 技术栈
后端技术
- Flask 2.3.3 - 轻量级Web框架
- SQLAlchemy 2.0.21 - ORM数据库操作
- Flask-SQLAlchemy 3.0.5 - Flask ORM扩展
- Flask-Login 0.6.3 - 用户认证管理
- Flask-Migrate 4.0.5 - 数据库迁移
- Flask-WTF 1.1.1 - 表单处理
- WTForms 3.0.1 - 表单验证
数据库
- MySQL - 主数据库
- SQLAlchemy - ORM框架
数据分析与机器学习
- NumPy 1.24.3 - 数值计算
- Pandas 2.0.3 - 数据分析
- Scikit-learn 1.3.0 - 机器学习算法
数据可视化
- Matplotlib 3.7.2 - 基础绘图
- Seaborn 0.12.2 - 统计图表
其他工具
- Pillow 10.0.0 - 图像处理
- Requests 2.31.0 - HTTP请求
- Python-dotenv 1.0.0 - 环境变量管理
💻 项目展示
🏗️ 系统架构
目录结构
网上厨房美食推荐系统/
├── app/ # 应用主目录
│ ├── __init__.py # 应用初始化
│ ├── models/ # 数据模型
│ │ ├── user.py # 用户模型
│ │ ├── recipe.py # 菜谱模型
│ │ ├── food.py # 食材模型
│ │ ├── category.py # 分类模型
│ │ ├── comment.py # 评论模型
│ │ ├── favorite.py # 收藏模型
│ │ └── ...
│ ├── routes/ # 路由控制器
│ │ ├── main.py # 主页路由
│ │ ├── auth.py # 认证路由
│ │ ├── user.py # 用户路由
│ │ ├── food.py # 食材路由
│ │ ├── recipe.py # 菜谱路由
│ │ ├── recommend.py # 推荐路由
│ │ ├── stats.py # 统计路由
│ │ └── admin.py # 管理路由
│ ├── templates/ # 模板文件
│ │ ├── base.html # 基础模板
│ │ ├── main/ # 主页模板
│ │ ├── auth/ # 认证模板
│ │ ├── user/ # 用户模板
│ │ ├── food/ # 食材模板
│ │ ├── recipe/ # 菜谱模板
│ │ ├── stats/ # 统计模板
│ │ └── admin/ # 管理模板
│ ├── static/ # 静态资源
│ │ ├── css/ # 样式文件
│ │ ├── js/ # JavaScript文件
│ │ └── images/ # 图片资源
│ ├── forms/ # 表单类
│ ├── services/ # 业务逻辑
│ ├── utils/ # 工具函数
│ └── config/ # 配置文件
├── data/ # 数据文件
├── migrations/ # 数据库迁移
├── uploads/ # 上传文件
├── requirements.txt # 依赖包
├── config.py # 配置文件
├── run.py # 启动文件
└── README.md # 项目说明
架构设计
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 前端界面 │ │ Flask应用 │ │ 数据库 │
│ (Templates) │◄──►│ (Routes) │◄──►│ (MySQL) │
└─────────────────┘ └─────────────────┘ └─────────────────┘│▼┌─────────────────┐│ 业务逻辑 ││ (Services) │└─────────────────┘│▼┌─────────────────┐│ 推荐算法 ││ (ML/Numpy) │└─────────────────┘
🔧 核心功能实现
1. 用户系统
# app/models/user.py
class User(UserMixin, db.Model):"""用户模型"""__tablename__ = 'users'id = db.Column(db.Integer, primary_key=True, autoincrement=True)username = db.Column(db.String(255), unique=True, nullable=False)password = db.Column(db.String(255), nullable=False)email = db.Column(db.String(255), unique=True, nullable=False)avatar = db.Column(db.String(255), default='/static/images/default-avatar.png')description = db.Column(db.Text)is_admin = db.Column(db.Boolean, default=False)last_login = db.Column(db.DateTime)created_at = db.Column(db.DateTime, default=datetime.utcnow)# 关系定义food_favorites = db.relationship('FoodFavorite', back_populates='user', lazy='dynamic')recipe_favorites = db.relationship('RecipeFavorite', back_populates='user', lazy='dynamic')def set_password(self, password):"""设置密码"""self.password = generate_password_hash(password)def check_password(self, password):"""验证密码"""return check_password_hash(self.password, password)
2. 菜谱模型
# app/models/recipe.py
class Recipe(db.Model):"""菜谱模型"""__tablename__ = 'recipes'id = db.Column(db.Integer, primary_key=True, autoincrement=True)title = db.Column(db.String(200), nullable=False, comment='菜谱标题')description = db.Column(db.Text, comment='菜谱描述')main_image = db.Column(db.String(500), comment='主图URL')category_id = db.Column(db.Integer, db.ForeignKey('ingredient_categories.id'), nullable=False)ingredients = db.Column(db.JSON, comment='食材列表')steps = db.Column(db.JSON, comment='步骤列表')collect_count = db.Column(db.Integer, default=0, comment='收藏数')comment_count = db.Column(db.Integer, default=0, comment='评论数')# 关联关系category = db.relationship('IngredientCategory', back_populates='recipes', lazy='joined')comments = db.relationship('RecipeComment', back_populates='recipe', lazy='dynamic')favorites = db.relationship('RecipeFavorite', back_populates='recipe', lazy='dynamic')
3. 应用初始化
# app/__init__.py
def create_app(config_name='default'):"""创建Flask应用"""app = Flask(__name__)# 加载配置app.config.from_object(config[config_name])config[config_name].init_app(app)# 初始化扩展db.init_app(app)migrate.init_app(app, db)login_manager.init_app(app)# 注册蓝图from app.routes import main, auth, user, food, recipe, recommend, stats, adminapp.register_blueprint(main.bp)app.register_blueprint(auth.bp)app.register_blueprint(user.bp)app.register_blueprint(food.bp)app.register_blueprint(recipe.bp)app.register_blueprint(recommend.bp, url_prefix='/recommend')app.register_blueprint(stats.bp)app.register_blueprint(admin.bp)return app
🗄️ 数据库设计
核心表结构
用户表 (users)
CREATE TABLE users (id INT PRIMARY KEY AUTO_INCREMENT,username VARCHAR(255) UNIQUE NOT NULL,password VARCHAR(255) NOT NULL,email VARCHAR(255) UNIQUE NOT NULL,avatar VARCHAR(255) DEFAULT '/static/images/default-avatar.png',description TEXT,is_admin BOOLEAN DEFAULT FALSE,last_login DATETIME,created_at DATETIME DEFAULT CURRENT_TIMESTAMP,updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
菜谱表 (recipes)
CREATE TABLE recipes (id INT PRIMARY KEY AUTO_INCREMENT,url VARCHAR(500) NOT NULL,title VARCHAR(200) NOT NULL,description TEXT,main_image VARCHAR(500),category_id INT NOT NULL,author_name VARCHAR(100),author_avatar VARCHAR(500),ingredients JSON,steps JSON,collect_count INT DEFAULT 0,comment_count INT DEFAULT 0,created_at DATETIME DEFAULT CURRENT_TIMESTAMP,updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,FOREIGN KEY (category_id) REFERENCES ingredient_categories(id)
);
收藏表 (recipe_favorites)
CREATE TABLE recipe_favorites (id INT PRIMARY KEY AUTO_INCREMENT,user_id INT NOT NULL,recipe_id INT NOT NULL,created_at DATETIME DEFAULT CURRENT_TIMESTAMP,FOREIGN KEY (user_id) REFERENCES users(id),FOREIGN KEY (recipe_id) REFERENCES recipes(id),UNIQUE KEY unique_user_recipe (user_id, recipe_id)
);
数据库关系图
users (用户表)
├── recipe_favorites (菜谱收藏)
├── food_favorites (食材收藏)
├── recipe_comments (菜谱评论)
├── food_comments (食材评论)
└── logs (用户日志)recipes (菜谱表)
├── recipe_favorites (收藏关系)
├── recipe_comments (评论关系)
└── logs (浏览日志)foods (食材表)
├── food_favorites (收藏关系)
└── food_comments (评论关系)ingredient_categories (分类表)
└── recipes (菜谱分类)
🤖 推荐算法
协同过滤算法实现
# app/routes/recommend.py
def get_recipe_recommendations(user_id, limit=10):"""获取菜谱推荐 - 基于协同过滤"""try:# 获取所有用户收藏favorites = RecipeFavorite.query.all()# 构建用户-菜谱矩阵user_recipe_dict = defaultdict(set)for fav in favorites:user_recipe_dict[fav.user_id].add(fav.recipe_id)# 获取当前用户的收藏user_favorites = user_recipe_dict.get(user_id, set())if not user_favorites:return []# 计算用户相似度 (Jaccard相似度)user_similarities = {}for other_user_id, other_favorites in user_recipe_dict.items():if other_user_id == user_id:continueintersection = len(user_favorites & other_favorites)union = len(user_favorites | other_favorites)if union > 0:similarity = intersection / unionuser_similarities[other_user_id] = similarity# 获取最相似的用户similar_users = sorted(user_similarities.items(), key=lambda x: x[1], reverse=True)[:5]# 获取推荐菜谱recommended_recipes = set()for similar_user_id, _ in similar_users:similar_user_favorites = user_recipe_dict[similar_user_id]# 只推荐当前用户未收藏的菜谱new_recipes = similar_user_favorites - user_favoritesrecommended_recipes.update(new_recipes)# 获取菜谱详情recipes = Recipe.query.filter(Recipe.id.in_(recommended_recipes))\.order_by(desc(Recipe.collect_count))\.limit(limit)\.all()return recipesexcept Exception as e:logger.error(f"获取菜谱推荐失败: {str(e)}", exc_info=True)return []
算法特点
- 协同过滤:基于用户行为的相似性推荐
- Jaccard相似度:计算用户收藏菜谱的相似度
- 冷启动处理:新用户无收藏时返回热门菜谱
- 实时更新:用户行为变化时推荐结果实时更新
📊 数据可视化
统计功能实现
# app/routes/stats.py
@bp.route('/api/stats/foods')
def food_stats():"""食材统计数据"""# 食材类型统计food_types = db.session.query(Food.food_type,func.count(Food.id).label('count')).group_by(Food.food_type).all()# 收藏数TOP10食材top_favorites = Food.query.order_by(Food.favorite_count.desc()).limit(10).all()# 食材收藏趋势(最近7天)seven_days_ago = datetime.now() - timedelta(days=7)daily_favorites = db.session.query(func.date(FoodFavorite.created_at).label('date'),func.count(FoodFavorite.id).label('count')).filter(FoodFavorite.created_at >= seven_days_ago)\.group_by('date').order_by('date').all()return jsonify({'food_types': [{'type': t[0], 'count': t[1]} for t in food_types if t[0]],'top_favorites': [{'title': f.title, 'count': f.favorite_count} for f in top_favorites],'daily_favorites': [{'date': d[0].strftime('%m-%d'), 'count': d[1]} for d in daily_favorites]})
可视化图表类型
- 饼图:食材类型分布、菜谱分类分布
- 柱状图:热门菜谱排行、用户活跃度
- 折线图:收藏趋势、用户注册趋势
- 散点图:菜谱热度分布
🚀 部署与优化
性能优化
-
数据库优化
- 建立合适的索引
- 使用连接查询减少查询次数
- 实现分页查询
-
缓存策略
- 热门菜谱缓存
- 用户推荐结果缓存
- 统计数据缓存
-
前端优化
- 图片懒加载
- 静态资源压缩
- 异步加载数据
部署方案
# 安装依赖
pip install -r requirements.txt# 初始化数据库
flask db init
flask db migrate
flask db upgrade# 启动应用
python run.py
✨ 项目特色
1. 智能推荐
- 基于协同过滤的个性化推荐
- 支持冷启动处理
- 实时更新推荐结果
2. 丰富的数据分析
- 多维度数据统计
- 实时数据可视化
- 用户行为分析
3. 完整的用户系统
- 用户注册登录
- 个人中心管理
- 社交互动功能
4. 响应式设计
- 适配多种设备
- 现代化UI设计
- 良好的用户体验
📈 总结与展望
项目成果
- 完整的菜谱推荐系统:实现了从数据采集到推荐展示的完整流程
- 智能推荐算法:基于协同过滤的个性化推荐,提高了用户满意度
- 丰富的数据分析:多维度统计和可视化,为运营决策提供支持
- 良好的用户体验:响应式设计和现代化UI,提升了用户粘性
技术亮点
- Flask + SQLAlchemy:轻量级但功能强大的Web框架
- NumPy + Pandas:高效的数据处理和分析
- Scikit-learn:机器学习算法的应用
- 协同过滤算法:个性化推荐的核心技术
未来展望
- 算法优化:引入深度学习模型,提升推荐精度
- 功能扩展:增加菜谱评分、营养分析等功能
- 性能提升:引入Redis缓存,提升系统响应速度
- 移动端适配:开发移动端应用,提升用户体验
技术收获
通过本项目的开发,深入学习了:
- Flask Web开发框架的使用
- 数据库设计和ORM操作
- 机器学习算法在实际项目中的应用
- 数据可视化和统计分析
- 前后端分离开发模式
这个项目不仅是一个功能完整的美食推荐系统,更是对现代Web开发技术栈的全面实践,为后续的技术学习和项目开发奠定了坚实的基础。
本文档详细介绍了基于Python的网上厨房美食推荐系统的技术实现,包括系统架构、核心功能、推荐算法、数据可视化等各个方面。项目采用Flask + SQLAlchemy + NumPy + Pandas等技术栈,实现了完整的菜谱推荐和管理功能。
源码获取:[码界筑梦坊各平台同名]