计算机毕业设计:基于Python与协同过滤的美食推荐可视化平台 Django框架 Vue 数据分析 推荐系统 推荐算法 机器学习 大数据(建议收藏)✅
1、项目介绍
技术栈
Python 语言、Django 框架、Vue 前端框架、MySQL 数据库、Echarts 可视化库、HTML、基于用户的协同过滤推荐算法
功能模块
- 首页美食信息模块
- 美食数据大屏模块
- 评分信息记录模块
- 我的评论模块
- 我的收藏模块
- 美食推荐模块
- 注册登录模块
- 管理员界面模块
- 个人中心模块
- 美食数据管理模块
项目介绍
本系统是基于 Python 与 Django 开发的美食推荐可视化平台,融合用户协同过滤算法为用户提供个性化美食推荐。系统首页集中展示各类美食基础信息,支持搜索与筛选。美食数据大屏通过 Echarts 呈现美食类型、发布时间、评分分布、收藏数区间及最受欢迎 TOP10 等多维度可视化图表。用户可对美食进行评分、评论与收藏,个人中心集中管理个人资料及互动记录。推荐模块基于用户评分行为,有评分记录时按用户偏好类型精准推荐,无记录时随机推荐 12 款美食以增加发现机会。后台管理员可对美食信息、用户数据进行增删改查与批量操作,保障平台数据准确性与运营规范性。
2、项目界面
(1)首页美食信息
该页面是美食推荐可视化平台的核心操作页,设有后台管理入口,支持美食名称的搜索与重置操作,可展示美食的各类基础信息及评分、评论、收藏相关数据,还能实现数据可视化展示与个性化推荐,同时配备个人信息查看、密码修改和系统退出的基础功能模块。

(2)美食数据大屏
该页面是美食推荐可视化平台的数据可视化分析大屏,设有后台管理入口,可通过各类图表可视化呈现美食类型、发布时间、分类的分布情况,还能展示美食评分和收藏数的区间分布数据,同时呈现最受欢迎TOP10美食相关数据,实现美食多维度数据的直观可视化展示与分析。

(3)评分信息记录
该页面是美食推荐可视化平台的评分信息管理页,设有后台管理入口,可展示用户的我的评分相关数据列表,包含评分对应的各类相关信息,支持对评分记录执行删除操作,同时可切换查看美食、评论、收藏等信息及进行数据可视化、个性化推荐操作,也配备个人信息查看、密码修改和系统退出功能。

(4)我的评论
该页面是美食推荐可视化平台的评论信息管理页,设有后台管理入口,核心展示用户的我的评论数据列表,呈现评论内容、时间等相关信息,支持分页查看评论数据,可切换至美食、评分、收藏等信息板块,也能进行数据可视化、个性化推荐操作,同时配备个人信息查看、密码修改和系统退出的基础功能。

(5)我的收藏
该页面是美食推荐可视化平台的收藏信息管理页,设有后台管理入口,核心展示用户的我的收藏数据列表,呈现收藏对应的美食编号、收藏时间等信息,支持对收藏记录执行取消收藏操作,可切换至美食、评分、评论等信息板块,也能进行数据可视化、个性化推荐操作,同时配备个人信息查看、密码修改和系统退出的基础功能。

(6)美食推荐
该页面是美食推荐可视化平台的个性化推荐页,设有后台管理入口,核心展示系统为用户推荐的各类美食信息,呈现美食的类型、分类、评分等基础信息及相关数据,可切换至美食、评分、评论、收藏等信息板块,也能进行数据可视化操作,同时配备个人信息查看、密码修改和系统退出的基础功能。

(7)注册登录
该页面是美食推荐可视化平台的账号登录页,设有后台管理入口,核心提供账号密码输入框和登录操作按钮,支持管理员相关登录权限选择,配备注册入口供新用户创建账号,同时展示平台的核心服务与功能亮点,为用户提供平台的登录与注册基础操作功能。

(8)管理员界面
该页面是美食推荐可视化平台的后台美食管理页,支持管理员进行美食信息的搜索、重置与新增操作,可展示美食的标题、评分、类型等全量信息,能对单条美食数据执行编辑、删除和查看详情的操作,同时配备用户管理相关功能入口,实现后台对美食数据的全方位管理与操作。

(9)个人中心
该页面是美食推荐可视化平台的个人信息管理页,设有后台管理入口,核心展示用户的用户名、姓名、电话等个人基础信息,支持对个人信息进行编辑并保存修改,可切换至美食、评分、评论等信息板块,也能进行数据可视化、个性化推荐操作,同时配备修改密码和系统退出的基础功能。

(10)美食数据管理
该页面是美食推荐可视化平台的高级后台美食管理页,支持主题切换与美食信息搜索,可批量选择和删除美食数据,能展示美食的评分、热度等全维度详细信息,同时配备收藏记录、用户、评分管理等功能入口,实现对美食数据的批量操作和全平台数据的综合管理。

3、项目说明
一、技术栈简要说明
系统后端采用 Python 语言与 Django 框架构建,前端使用 Vue 框架实现响应式交互,数据库选用 MySQL 进行数据存储。可视化部分通过 Echarts 图表库实现美食类型分布、评分区间、收藏数排行等多种数据图表的渲染展示。推荐模块基于用户协同过滤算法,根据用户历史评分行为生成个性化推荐结果。
二、功能模块详细介绍
· 首页美食信息模块
作为平台核心操作页,集中展示各类美食的名称、图片、简介、所属品类等基础信息,支持按美食名称进行搜索与重置筛选,同时展示评分、评论、收藏等相关数据,并配备数据可视化与个性化推荐入口。
· 美食数据大屏模块
基于 Echarts 构建的数据可视化分析大屏,通过多种图表直观呈现美食类型分布、发布时间趋势、分类占比、评分区间分布、收藏数区间分布以及最受欢迎 TOP10 美食等数据,实现多维度数据的可视化展示。
· 评分信息记录模块
管理用户对美食的评分行为记录,展示评分分值、评分时间、对应美食名称等信息,支持对个人评分记录进行删除操作,为推荐模块提供核心数据来源。
· 我的评论模块
用户个人评论管理板块,以列表形式展示用户发布的评论内容、评论时间等信息,支持分页查看,用户可管理自己的美食评价与反馈。
· 我的收藏模块
用户收藏功能管理页面,展示用户收藏的美食列表及收藏时间,支持取消收藏操作,方便用户快速查找与管理心仪美食。
· 美食推荐模块
平台核心功能,基于用户协同过滤算法,根据用户历史评分行为动态生成推荐结果。有评分记录时按用户偏好美食类型精准推荐,无评分记录时随机推荐 12 款美食,兼顾推荐精准性与多样性。
· 注册登录模块
基础账号功能页面,提供账号密码输入框与登录操作按钮,支持新用户注册与老用户登录,是用户使用评分、评论、收藏等个性化功能的前提。
· 管理员界面模块
后台美食管理入口,支持管理员进行美食信息的搜索、重置与新增操作,可对单条美食数据执行编辑、删除和详情查看,同时配备用户管理功能入口,实现后台数据全方位管控。
· 个人中心模块
用户个人信息管理页面,展示用户名、姓名、电话等基础信息,支持编辑保存个人资料,同时提供修改密码功能,整合用户个性化操作入口。
· 美食数据管理模块
高级后台管理功能,支持主题切换与美食信息搜索,可批量选择与删除美食数据,展示评分、热度等全维度详细信息,同时配备收藏记录、用户管理、评分管理等入口,实现全平台数据的综合管理。
三、项目总结
本系统是基于 Python 与 Django 开发的美食推荐可视化平台,融合用户协同过滤算法为用户提供个性化美食推荐服务。系统首页集中展示美食基础信息并支持搜索筛选,美食数据大屏通过 Echarts 呈现类型分布、评分区间、收藏排行等多维度可视化图表。用户可对美食进行评分、评论与收藏,个人中心集中管理个人资料与互动记录。推荐模块基于用户评分行为,有记录时按偏好类型精准推荐,无记录时随机推荐 12 款美食以增加发现机会。后台提供管理员界面与美食数据管理功能,支持美食信息的增删改查与批量操作,保障平台数据准确性与运营规范性。
4、核心代码
from django.shortcuts import render,redirect
from django.core.paginator import Paginator
# Create your views here.
from .utils import getPublicData
from .utils import getFenxiData
from .utils.error import *
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods
import json
from .crud_base import CRUDBase
import pymysql
def tuijian(request):
if request.method == 'POST':
data = json.loads(request.body)
userid = data['userid']
print(userid)
# 获取用户评分过的漫画类型
user_rated_types = getPublicData.querys(
"""
SELECT DISTINCT m.style
FROM mh m
INNER JOIN rate r ON r.prodid = m.id
WHERE r.userid = %s
""",
[userid],
'select'
)
# 如果用户有评分记录,推荐相同类型的漫画
if user_rated_types:
style_list = [t[0] for t in user_rated_types]
style_conditions = " OR ".join(["style = %s"] * len(style_list))
# 获取相同类型的其他漫画
datalist = getPublicData.querys(
f"""
SELECT * FROM mh
WHERE {style_conditions}
ORDER BY RAND()
LIMIT 12
""",
style_list,
'select'
)
else:
# 如果用户没有评分记录,随机推荐漫画
datalist = getPublicData.querys(
"SELECT * FROM mh ORDER BY RAND() LIMIT 12",
[],
'select'
)
# 构建返回数据
data_list = []
fields = ['id', 'title', 'detail_url', 'style', 'area', 'price',
'status', 'authors', 'description', 'cover_url', 'froms']
for item in datalist:
node = {}
for index, field in enumerate(fields):
node[field] = item[index]
data_list.append(node)
return JsonResponse({'code': '200', 'msg': '成功', 'data': data_list})
def adminupdate(request):
if request.method == 'PUT':
data = json.loads(request.body)
print(data)
id = data['id']
username = data['username']
name = data['name']
role = data['role']
phone = data['phone']
q = "update admin set username = '" + username + "',name='" + name + "',role='" + role + "',phone='" + phone + "'where id = " + str(
id)
getPublicData.querys(q, [], 'no_select')
return JsonResponse({'code': '200', 'msg': '成功', 'data': None})
def adminupdatePassword(request):
if request.method == 'PUT':
data = json.loads(request.body)
print(data)
id = data['id']
newPassword = data['newPassword']
q = "update admin set password = '" + newPassword + "'where id = " + str(
id)
getPublicData.querys(q, [], 'no_select')
return JsonResponse({'code': '200', 'msg': '成功', 'data': None})
def personupdate(request):
if request.method == 'PUT':
data = json.loads(request.body)
print(data)
id = data['id']
username = data['username']
name = data['name']
role = data['role']
phone = data['phone']
q = "update user set username = '" + username + "',name='" + name + "',role='" + role + "',phone='" + phone + "'where id = " + str(
id)
getPublicData.querys(q,[],'no_select')
return JsonResponse({'code': '200', 'msg': '成功', 'data': None})
def personupdatePassword(request):
if request.method == 'PUT':
data = json.loads(request.body)
print(data)
id = data['id']
password = data['newPassword']
q = "update user set password = '" + password + "'where id = " + str(
id)
getPublicData.querys(q,[],'no_select')
return JsonResponse({'code': '200', 'msg': '成功', 'data': None})
class UserCRUD(CRUDBase):
def __init__(self):
super().__init__(
table_name='user',
fields=['id', 'username', 'password', 'name', 'role', 'phone'],
required_fields = ['username', 'password'] # 设置必填字段
)
def list(self, request) -> JsonResponse:
if request.method != 'POST':
return JsonResponse({'code': '5004', 'msg': '请求方法错误', 'data': None})
try:
data = json.loads(request.body)
username = data.get('username')
if username:
sql = f'''SELECT * FROM `{self.table_name}`
WHERE username LIKE CONCAT('%%', %s, '%%')'''
result = getPublicData.querys(sql, [username], 'select')
else:
sql = f'SELECT * FROM `{self.table_name}`'
result = getPublicData.querys(sql, [], 'select')
# 格式化返回数据
data_list = []
for item in result:
node = {}
for index, field in enumerate(self.fields):
node[field] = item[index]
data_list.append(node)
return JsonResponse({'code': '200', 'data': {'list': data_list}})
except Exception as e:
return JsonResponse({'code': '5004', 'msg': str(e), 'data': None})
user_crud = UserCRUD()
def userlist(request):
return user_crud.list(request)
def useradd(request):
return user_crud.add(request)
def userdelete(request):
return user_crud.delete(request)
def userupdate(request):
return user_crud.update(request)
class CommentCRUD(CRUDBase):
def __init__(self):
super().__init__(
table_name='comment',
fields=['id', 'content', 'userid', 'prodid', 'time'],
required_fields = ['content', 'userid', 'prodid'] # 设置必填字段
)
comment_crud = CommentCRUD()
def commentlist(request):
return comment_crud.list(request)
def commentadd(request):
return comment_crud.add(request)
def commentdelete(request):
return comment_crud.delete(request)
def commentupdate(request):
return comment_crud.update(request)
class RateCRUD(CRUDBase):
def __init__(self):
super().__init__(
table_name='rate',
fields=['id', 'score', 'userid', 'prodid', 'time'],
required_fields = ['score', 'userid', 'prodid'] # 设置必填字段
)
rate_crud = RateCRUD()
def ratelist(request):
return rate_crud.list(request)
def rateadd(request):
return rate_crud.add(request)
def ratedelete(request):
return rate_crud.delete(request)
def rateupdate(request):
return rate_crud.update(request)
class CollectCRUD(CRUDBase):
def __init__(self):
super().__init__(
table_name='collect',
fields=['id', 'userid', 'prodid', 'time'],
required_fields = ['userid', 'prodid']
)
collect_crud = CollectCRUD()
def collectlist(request):
return collect_crud.list(request)
def collectadd(request):
return collect_crud.add(request)
def collectdelete(request):
return collect_crud.delete(request)
def collectupdate(request):
return collect_crud.update(request)
def login(request):
if request.method =='GET':
return render(request, 'Login.html')
else:
data =json.loads(request.body)
print(data)
username = data['username']
password = data['password']
role = data['role']
print(username, password, role)
if role=='ADMIN':
users =getPublicData.querys(f"select * from `admin` where username='{username}' and password='{password}'", [],'select')
if users:
return JsonResponse({'code': '200', 'data': {
'role': users[0][4],
'id': users[0][0],
'name': users[0][3],
'password': users[0][2],
'phone': users[0][5],
'username': users[0][1],
}})
else:
return JsonResponse({'code': '5004', 'msg': '用户不存在', 'data': None})
else:
users = getPublicData.querys(f"select * from `user` where username='{username}' and password='{password}'",
[], 'select')
if users:
return JsonResponse({'code': '200', 'data': {
'role': users[0][4],
'id': users[0][0],
'name': users[0][3],
'password': users[0][2],
'phone': users[0][5],
'username': users[0][1],
}})
else:
return JsonResponse({'code': '5004', 'msg': '用户不存在', 'data': None})
def registry(request):
if request.method == 'POST':
data = json.loads(request.body)
print(data)
username = data['username']
password = data['password']
name = data['name']
role = data['role']
phone = data['phone']
getPublicData.querys('''insert into user(username,password,name,role,phone) values(%s,%s,%s,%s,%s) ''',
[username, password, name, role,phone])
return JsonResponse({'code': '200', 'msg': '注册成功', 'data': None})
def logOut(request):
request.session.clear()
return redirect('login')
class FoodCRUD(CRUDBase):
def __init__(self):
super().__init__(
table_name='food',
fields=['id', 'title', 'cover', 'score', 'redu', 'sc',
'biaoqian', 'yuanliao', 'js', 'shijian', 'type',
'category', 'fbr', 'fbrdetail', 'detail']
)
food_crud = FoodCRUD()
def food_list(request):
return food_crud.list(request)
def food_add(request):
return food_crud.add(request)
def food_delete(request):
return food_crud.delete(request)
def food_update(request):
return food_crud.update(request)
def get_food_analysis(request):
try:
data = {
'type_data': getFenxiData.get_food_type_count(),
'category_data': getFenxiData.get_food_category_count(),
'rate_data': getFenxiData.get_top_rated_food(),
'collect_data': getFenxiData.get_top_collected_food(),
'comment_data': getFenxiData.get_top_commented_food(),
'popular_data': getFenxiData.get_most_popular_food()
}
return JsonResponse({'code': '200', 'msg': '成功', 'data': data})
except Exception as e:
return JsonResponse({'code': '5004', 'msg': f'获取分析数据失败:{str(e)}', 'data': None})
def get_time_distribution(request):
if request.method == 'GET':
try:
data = getFenxiData.get_time_distribution()
return JsonResponse({
'code': '200',
'msg': '成功',
'data': [
{
'time_period': item[0],
'count': item[1]
}
for item in data
]
})
except Exception as e:
return JsonResponse({
'code': '5004',
'msg': f'获取时间分布统计失败:{str(e)}',
'data': None
})
def get_score_distribution(request):
if request.method == 'GET':
try:
data = getFenxiData.get_score_distribution()
return JsonResponse({
'code': '200',
'msg': '成功',
'data': [
{
'score_range': item[0],
'count': item[1]
}
for item in data
]
})
except Exception as e:
return JsonResponse({
'code': '5004',
'msg': f'获取评分分布统计失败:{str(e)}',
'data': None
})
def get_collection_distribution(request):
if request.method == 'GET':
try:
data = getFenxiData.get_collection_distribution()
return JsonResponse({
'code': '200',
'msg': '成功',
'data': [
{
'collection_range': item[0],
'count': item[1]
}
for item in data
]
})
except Exception as e:
return JsonResponse({
'code': '5004',
'msg': f'获取收藏分布统计失败:{str(e)}',
'data': None
})
更多推荐
所有评论(0)