博主介绍:✌全网粉丝50W+,前互联网大厂软件研发、集结硕博英豪成立软件开发工作室,专注于计算机相关专业项目实战6年之久,累计开发项目作品上万套。凭借丰富的经验与专业实力,已帮助成千上万的学生顺利毕业,选择我们,就是选择放心、选择安心毕业✌
> 🍅想要获取完整文章或者源码,或者代做,拉到文章底部即可与我联系了。🍅🍅**感兴趣的可以先收藏起来,点赞、关注不迷路,大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助同学们顺利毕业 。**🍅
1、毕业设计:2026年计算机专业毕业设计选题汇总(建议收藏)✅
1、项目介绍
技术栈
Python 语言、Django 框架、Vue 前端框架、MySQL 数据库、Echarts 可视化库、HTML、基于用户的协同过滤推荐算法
功能模块
- 首页美食信息模块
- 美食数据大屏模块
- 评分信息记录模块
- 我的评论模块
- 我的收藏模块
- 美食推荐模块
- 注册登录模块
- 管理员界面模块
- 个人中心模块
- 美食数据管理模块
项目介绍
本系统基于 Python 与 Django 开发,融合 Vue 前端框架与 Echarts 可视化工具,构建美食推荐与数据可视化平台。系统采用基于用户的协同过滤推荐算法,用户有评分记录时按偏好类型精准推荐,无记录时随机推荐 12 款美食以增加发现机会。首页以卡片形式展示美食信息,支持搜索筛选与收藏、评分、评论操作。美食数据大屏通过图表展示类型分布、最受欢迎 Top10、评分及收藏区间等可视化分析。用户可在个人中心管理评分、评论与收藏记录,后台管理员支持美食信息的增删改查与批量操作,实现平台数据的统一维护。
2、项目界面
(1)首页美食信息
该页面是美食推荐可视化平台的美食信息展示页,支持美食名称搜索与类型筛选,以卡片形式呈现美食图片、名称、类型、分类、评分等信息,配备收藏、评分、评论操作按钮,同时具备评分信息、评论信息、数据可视化、个性化推荐及个人信息管理等功能模块。

(2)美食数据大屏
该页面是美食推荐可视化平台的数据可视化分析大屏,展示美食类型分布、美食分类分布、最受欢迎top10美食、美食发布时间分布、评分区间分布及收藏数区间分布,同时具备美食信息管理、个性化推荐、个人信息管理等功能模块。

(3)评分信息记录
该页面是美食推荐可视化平台的评分信息页,以列表形式展示用户的历史评分记录,包含评分星级、美食编号、评分时间等信息,支持删除操作,同时具备美食信息管理、评论信息管理、收藏信息管理、数据可视化、个性化推荐及个人信息管理等功能模块。

(4)我的评论
该页面是美食推荐可视化平台的评论信息页,支持评论内容搜索,以列表形式展示用户的历史评论记录,包含评论内容、评论时间、美食编号等信息,支持编辑和删除操作,同时具备美食信息管理、评分信息管理、收藏信息管理、数据可视化、个性化推荐及个人信息管理等功能模块。

(5)我的收藏
该页面是美食推荐可视化平台的收藏信息页,以列表形式展示用户的历史收藏记录,包含美食编号、收藏时间等信息,支持取消收藏操作,同时具备美食信息管理、评分信息管理、评论信息管理、数据可视化、个性化推荐及个人信息管理等功能模块。

(6)美食推荐
该页面是美食推荐可视化平台的个性化推荐页,基于用户行为以卡片形式智能推荐美食内容,展示美食图片、名称、类型、分类、评分等信息,同时具备美食信息管理、评分信息管理、评论信息管理、收藏信息管理、数据可视化及个人信息管理等功能模块。

(7)注册登录
该页面是健康美食推荐可视化平台的登录页,提供账号、密码输入框与角色选择下拉框,设有登录按钮和注册入口,同时展示平台核心功能介绍,完成身份验证后可进入系统使用智能推荐、健康美食、大数据分析等功能模块。

(8)管理员界面
该页面是美食推荐可视化平台的后台美食信息管理页,支持美食标题搜索与新增操作,以列表形式展示美食ID、标题、封面、评分、热度、收藏数等信息,配备编辑、删除、详情操作按钮,同时具备用户信息管理等后台功能模块。

(9)个人中心
该页面是美食推荐可视化平台的个人信息页,展示并支持修改用户的用户名、姓名和电话信息,配备保存修改按钮,同时具备美食信息管理、评分信息管理、评论信息管理、收藏信息管理、数据可视化及个性化推荐等功能模块。

(10)美食数据管理
该页面是美食推荐可视化平台的后台美食管理页,支持多条件搜索与批量操作,以列表形式展示美食标题、评分、热度、收藏数、原料、介绍、发布时间等信息,配备增加、删除、分页等操作按钮,同时具备收藏记录管理、用户管理、管理员信息、评分管理、评论管理等后台功能模块。

3、项目说明
一、技术栈简要说明
系统后端采用 Python 语言与 Django 框架构建,前端使用 Vue 框架实现响应式交互,数据库选用 MySQL 进行数据存储。可视化部分通过 Echarts 图表库实现类型分布、评分区间、收藏排行等多种数据图表的渲染展示。推荐模块基于用户的协同过滤算法,根据用户历史评分行为生成个性化推荐结果。
二、功能模块详细介绍
· 首页美食信息模块
支持美食名称搜索与类型筛选,以卡片形式呈现美食图片、名称、类型、分类、评分等信息,配备收藏、评分、评论操作按钮,是用户浏览美食的核心入口。
· 美食数据大屏模块
基于 Echarts 构建的数据可视化分析大屏,展示美食类型分布、美食分类分布、最受欢迎 top10 美食、美食发布时间分布、评分区间分布及收藏数区间分布,实现多维度数据的可视化呈现。
· 评分信息记录模块
以列表形式展示用户的历史评分记录,包含评分星级、美食编号、评分时间等信息,支持删除操作,为推荐模块提供核心数据来源。
· 我的评论模块
支持评论内容搜索,以列表形式展示用户的历史评论记录,包含评论内容、评论时间、美食编号等信息,支持编辑和删除操作,方便用户管理个人评价。
· 我的收藏模块
以列表形式展示用户的历史收藏记录,包含美食编号、收藏时间等信息,支持取消收藏操作,满足用户个性化的美食收藏与管理需求。
· 美食推荐模块
平台核心功能,基于用户的协同过滤算法,有评分记录时按用户评分过的美食类型精准推荐,无评分记录时随机推荐 12 款美食,兼顾推荐精准性与多样性。
· 注册登录模块
提供账号、密码输入框与角色选择下拉框,设有登录按钮和注册入口,完成身份验证后可进入系统使用智能推荐、数据可视化等功能模块。
· 管理员界面模块
后台美食信息管理入口,支持美食标题搜索与新增操作,以列表形式展示美食 ID、标题、封面、评分、热度、收藏数等信息,配备编辑、删除、详情操作按钮,同时具备用户信息管理等后台功能。
· 个人中心模块
展示并支持修改用户的用户名、姓名和电话信息,配备保存修改按钮,同时集成美食信息管理、评分信息管理、评论信息管理、收藏信息管理、数据可视化及个性化推荐等功能入口。
· 美食数据管理模块
后台高级管理功能,支持多条件搜索与批量操作,以列表形式展示美食标题、评分、热度、收藏数、原料、介绍、发布时间等信息,配备增加、删除、分页等操作按钮,同时具备收藏记录管理、用户管理、评分管理、评论管理等后台功能,实现全平台数据的综合维护。
三、项目总结
本系统基于 Python 与 Django 开发,融合 Vue 前端框架与 Echarts 可视化工具,构建美食推荐与数据可视化平台。系统采用基于用户的协同过滤推荐算法,用户有评分记录时按偏好类型精准推荐,无记录时随机推荐 12 款美食以增加发现机会。首页以卡片形式展示美食信息,支持搜索筛选与收藏、评分、评论操作。美食数据大屏通过图表展示类型分布、最受欢迎 Top10、评分及收藏区间等可视化分析。用户可在个人中心管理评分、评论与收藏记录,后台管理员支持美食信息的增删改查与批量操作,实现平台数据的统一维护。
4、核心代码
python
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
})