Django+Vue控糖食物推荐系统毕设包:从环境搭建到推荐算法实战
简介这份资源是面向高校计算机相关专业毕业设计的完整项目包主题为基于Django与Vue的控糖食物推荐系统适合正在准备毕设、需要可运行源码与配套文档的本科生或自学者。项目围绕糖尿病患者及健康人群的饮食管理需求实现用户注册登录、个人信息设定、食物数据管理、推荐算法设计与推荐结果展示等模块后端采用Django框架与ORM处理数据前端使用Vue.js构建单页应用推荐环节结合协同过滤与内容推荐思路综合血糖目标、营养需求与饮食偏好给出个性化建议。压缩包共538个文件约38.93MB包含93个vue组件、42个Python脚本、57个JavaScript文件以及sql数据库脚本、doc设计文档、mp4演示视频和bat启动脚本等覆盖前后端源码、数据库设计与运行演示。已有70人学习下载可帮助读者快速理解系统架构、复用推荐逻辑并完成毕设答辩准备。1. 从一份控糖推荐毕设包说起它到底能不能跑起来如果你正在做基于 Django 和 Vue 的毕业设计又恰好抽到“控糖食物推荐”这类偏健康管理的题目大概率会经历一个很拧巴的阶段算法想用协同过滤数据想用真实食物营养成分前端还想做得像模像样结果时间全耗在环境配置和接口联调上。这份《基于Djangovue控糖食物推荐系统源码数据库文档演示视频.zip》就是冲着这个痛点来的——它把后端、前端、数据库脚本和演示视频打包在一起让你先把系统跑通再回头改算法和界面。适合谁适合已经学过 Python 基础、知道 Vue 大概长什么样、但没完整做过一个前后端分离项目的同学。不适合谁如果你连pip install都没用过建议先补一下命令行基础否则后面每一步都会卡住。我见过太多人拿到包之后直接双击manage.py然后报一堆 ModuleNotFoundError最后说“这源码是假的”。其实不是源码假是打开方式不对。2. 拆包先看结构Django 后端与 Vue 前端怎么分家2.1 目录层级与关键文件定位拿到压缩包之后第一件事不是急着装依赖而是把目录树看清楚。常见做法是解压后得到两个主文件夹一个放 Django 工程一个放 Vue 工程外加一个db或sql文件夹存数据库脚本。我一般会先用tree -L 2或者直接在文件管理器里展开两层确认下面这些关键文件存在manage.pyDjango 的入口没有它后端就跑不起来。settings.py数据库配置、注册的 app、中间件都在这里后面改数据库连接就靠它。requirements.txt或pipfile后端依赖清单有它才能一次性装齐。package.json前端依赖清单Vue 的启动脚本和依赖版本都写在这。.sql文件数据库结构和初始数据控糖食物推荐系统一般会预置食物营养成分表和用户表。如果解压后发现只有一堆.py和.vue文件没有requirements.txt那就要手动补依赖。常见做法是看settings.py里INSTALLED_APPS引用了哪些第三方包再逐个pip install。这一步别偷懒否则后面报错会一个接一个。2.2 后端依赖安装与数据库初始化确认结构之后先搞后端。我一般会新建一个虚拟环境避免和系统 Python 打架。命令如下# 创建虚拟环境python3 -m venv 是标准做法 python3 -m venv venv # 激活虚拟环境Windows 用 venv\Scripts\activate source venv/bin/activate # 安装后端依赖-i 指定国内镜像源加快速度 pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple这里有几个参数值得注意-i后面跟的是镜像源地址如果你所在网络访问官方源很慢换成清华或阿里源会快很多。requirements.txt里通常会包含Django、djangorestframework、mysqlclient或pymysql、django-cors-headers等。装完之后别急着runserver先把数据库建好。数据库脚本一般在db文件夹里文件名可能是kangtang.sql或food_recommend.sql。我习惯用 MySQL 命令行导入# 先登录 MySQL-u 用户名 -p 表示输入密码 mysql -u root -p # 创建数据库字符集用 utf8mb4 避免中文乱码 CREATE DATABASE kangtang DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; # 退出 MySQL 后在命令行导入 SQL 文件 mysql -u root -p kangtang db/kangtang.sql导入完成后回到 Django 的settings.py把DATABASES里的NAME、USER、PASSWORD、HOST、PORT改成你本地的配置。这里有个血泪经验如果PASSWORD为空写成不要写None否则 Django 会报类型错误。改完之后执行迁移# 生成迁移文件--run-syncdb 在某些情况下可以跳过已有表 python manage.py makemigrations # 应用迁移到数据库 python manage.py migrate # 创建超级管理员方便进后台看数据 python manage.py createsuperuser如果migrate报错说表已存在说明 SQL 脚本里已经建了表这时候可以加--fake参数跳过或者直接注释掉settings.py里对应的 app 迁移。这一步的坑在于SQL 脚本和 Django 模型可能不完全一致导致字段类型对不上。常见做法是先用 SQL 脚本建表然后把 Django 模型里的managed False加上让 Django 不管理这些表。2.3 前端依赖安装与接口代理配置后端跑起来之后前端相对简单但坑也不少。进入 Vue 工程目录先看package.json里的scripts通常会有serve或dev。安装依赖# 进入前端目录 cd frontend # 安装依赖--registry 指定淘宝镜像 npm install --registryhttps://registry.npmmirror.com # 启动开发服务器 npm run serve启动之后浏览器打开http://localhost:8080如果页面能出来但数据是空的大概率是接口代理没配好。Vue 工程里一般有个vue.config.js或.env.development里面会写proxy配置。常见做法是把/api开头的请求代理到 Django 的http://127.0.0.1:8000// vue.config.js 里的 devServer 配置 module.exports { devServer: { proxy: { /api: { target: http://127.0.0.1:8000, // Django 后端地址 changeOrigin: true, // 允许跨域 pathRewrite: { ^/api: } // 去掉 /api 前缀 } } } }这里changeOrigin设为true是为了让后端看到的请求来源是代理服务器而不是浏览器避免 CORS 报错。pathRewrite则取决于后端路由是怎么写的如果后端本身就是/api/foods/那就不需要重写。改完vue.config.js要重启前端服务否则配置不生效。3. 推荐算法怎么接从食物成分表到协同过滤3.1 控糖推荐的数据基础与特征选择控糖食物推荐的核心不是算法多高级而是数据特征选得对不对。这份资源里一般会有一张食物营养成分表字段包括食物名称、GI 值升糖指数、GL 值血糖负荷、碳水化合物、膳食纤维、蛋白质、脂肪等。GI 值越低对血糖影响越小GL 值则结合了摄入量更贴近实际。我一般会先看数据库里这张表有多少条记录如果只有几十条那推荐结果会很单一需要自己补数据。特征选择上常见做法是把 GI 和 GL 作为主要排序依据再结合用户偏好做过滤。比如用户有糖尿病史那就优先推荐 GI 55 的食物如果用户只是控糖减脂可以放宽到 GI 70。这些阈值不要写死在代码里最好放在配置表或常量文件里方便后面调。3.2 协同过滤与基于内容的推荐怎么选毕业设计里常见的推荐算法有两种协同过滤和基于内容的推荐。协同过滤需要用户-物品评分矩阵但控糖场景下用户评分数据往往很少冷启动问题严重。基于内容的推荐则依赖食物特征和用户画像更适合这个场景。我一般会建议先用基于内容的推荐把系统跑通再叠加协同过滤做混合推荐。基于内容的推荐实现逻辑不复杂把用户画像比如年龄、BMI、血糖水平、忌口和食物特征做匹配算一个相似度分数。下面是一个简化的 Python 示例放在 Django 的recommend.py里# 基于内容的控糖食物推荐输入用户画像和食物列表 def content_based_recommend(user_profile, food_list, top_n10): user_profile: dict, 包含 bmi, blood_sugar, avoid_food 等字段 food_list: list of dict, 每个食物包含 gi, gl, carbs, fiber 等字段 top_n: 返回推荐数量 scored [] for food in food_list: score 0 # GI 值越低得分越高55 以下给满分 if food[gi] 55: score 40 elif food[gi] 70: score 20 # 膳食纤维越高得分越高每克加 2 分上限 20 score min(food[fiber] * 2, 20) # 如果用户有忌口直接跳过 if food[name] in user_profile.get(avoid_food, []): continue # BMI 偏高时优先低热量食物 if user_profile[bmi] 24 and food[calories] 150: score 15 scored.append((food, score)) # 按得分降序排序取前 top_n scored.sort(keylambda x: x[1], reverseTrue) return [item[0] for item in scored[:top_n]]这段代码的逻辑说明score是累加值GI 和纤维是主要权重BMI 是辅助权重。参数top_n控制返回数量默认 10 条。avoid_food是用户忌口列表直接从用户画像里读。实际项目中这些权重最好做成可配置的比如放在settings.py里定义一个RECOMMEND_WEIGHTS字典方便后期调优。3.3 接口联调与推荐结果落库算法写完之后要把它接到 Django 的视图里再通过 DRF 暴露成 API。常见做法是写一个RecommendView接收用户 ID调用推荐函数返回 JSON。前端拿到数据后渲染成卡片列表。这里有个容易翻车的地方推荐结果如果每次都实时计算数据量大时响应会很慢。我一般会加一个缓存层用 Redis 或者 Django 的cache框架把推荐结果缓存 10 分钟。# views.py 里的推荐接口示例 from django.core.cache import cache from rest_framework.views import APIView from rest_framework.response import Response class RecommendView(APIView): def get(self, request, user_id): cache_key frecommend_{user_id} result cache.get(cache_key) if not result: user UserProfile.objects.get(iduser_id) foods Food.objects.all().values() result content_based_recommend(user.__dict__, list(foods)) cache.set(cache_key, result, 600) # 缓存 10 分钟 return Response(result)cache.set的第三个参数是过期时间单位秒。600 秒意味着 10 分钟内同一个用户的推荐结果不变既减轻数据库压力又不会让用户觉得推荐一直没变化。如果用户修改了忌口或 BMI记得在保存时删掉对应的缓存键否则会一直返回旧结果。4. 避坑与排查跑不起来时先看这几条4.1 数据库连接报错Access denied 与字符集问题现象执行migrate或启动服务时报django.db.utils.OperationalError: (1045, Access denied for user rootlocalhost)。原因settings.py里的数据库密码和本地 MySQL 密码不一致或者 MySQL 用户没有远程/本地权限。解决先确认settings.py里的PASSWORD字段再登录 MySQL 执行ALTER USER rootlocalhost IDENTIFIED BY 新密码;并FLUSH PRIVILEGES;。如果报的是字符集错误比如Unknown character set: utf8mb4说明 MySQL 版本太低升级到 5.7 以上即可。4.2 前端跨域CORS 报错与代理失效现象浏览器控制台报Access to XMLHttpRequest at http://127.0.0.1:8000/api/foods/ from origin http://localhost:8080 has been blocked by CORS policy。原因Django 没有配置跨域中间件或者 Vue 的代理没生效。解决后端安装django-cors-headers在settings.py的INSTALLED_APPS和MIDDLEWARE里注册并设置CORS_ALLOW_ALL_ORIGINS True仅开发环境。前端检查vue.config.js的proxy配置改完必须重启npm run serve否则配置不加载。4.3 依赖版本冲突Django 与 DRF 对不上现象pip install -r requirements.txt之后启动报ImportError: cannot import name ugettext_lazy from django.utils.translation。原因Django 4.0 之后移除了ugettext_lazy但旧代码还在用。解决要么把 Django 降到 3.2要么把代码里的ugettext_lazy全部替换成gettext_lazy。我一般建议直接降级因为毕设代码里这种旧写法很多逐个改太费时间。命令是pip install django3.2.18。4.4 静态文件 404Vue 打包后 Django 找不到资源现象前端npm run build之后把dist放到 Django 的static目录访问页面白屏控制台报 404。原因Django 的STATIC_URL和STATICFILES_DIRS没配好或者 Vue 的publicPath不对。解决在settings.py里设置STATICFILES_DIRS [os.path.join(BASE_DIR, dist/static)]并在urls.py里加上static(settings.STATIC_URL, document_rootsettings.STATIC_ROOT)。Vue 那边把vue.config.js里的publicPath改成./重新打包。4.5 推荐结果为空数据表没数据或字段名对不上现象接口返回[]但数据库里明明有食物记录。原因推荐函数里用的字段名和数据库实际字段名不一致比如代码里写food[gi]但数据库字段是GI或glycemic_index。解决先用python manage.py shell进去执行Food.objects.first().__dict__看实际字段名再改推荐函数里的键名。另外确认Food模型有没有加managed False如果加了Django 不会自动同步表结构需要手动核对。5. 进阶技巧把演示视频里的流程变成自己的验证清单演示视频通常只展示“点这里、点那里”的顺畅流程但真正跑起来之后你需要一套自己的验证清单。我一般会按下面这个顺序走一遍每步都确认输出符合预期再往下走步骤验证内容预期结果常见异常1后端runserver终端显示Starting development server at http://127.0.0.1:8000/端口被占用换 80012访问/admin出现 Django 登录页数据库没迁移报错3前端npm run serve浏览器打开localhost:8080有页面依赖没装全看node_modules4登录系统能进主页看到食物列表接口 404检查代理5触发推荐返回 10 条食物GI 值合理返回空检查字段名6修改用户画像推荐结果发生变化缓存没清等 10 分钟这个清单我每次拿到新包都会跑一遍基本能覆盖 90% 的启动问题。另外演示视频里如果展示了“协同过滤”效果但源码里只有基于内容的推荐那说明视频可能是用另一版代码录的。这时候别纠结先把基于内容的推荐跑通再自己补协同过滤模块。我一般会加一个hybrid_recommend函数把两种算法的得分加权求和权重设成 0.6 和 0.4效果比单用一种稳。还有一个容易被忽略的点控糖推荐系统的用户画像表里血糖水平字段可能是枚举值比如“正常”“偏高”“糖尿病”而不是数值。推荐函数里如果直接拿它做数值比较会报类型错误。常见做法是写一个映射字典把枚举转成数值权重# 血糖水平映射数值越高代表需要越严格控糖 BLOOD_SUGAR_WEIGHT { 正常: 1.0, 偏高: 1.5, 糖尿病: 2.0 } # 在推荐函数里这样用 weight BLOOD_SUGAR_WEIGHT.get(user_profile[blood_sugar], 1.0) score score * weight这样调整之后糖尿病用户的推荐结果会更偏向低 GI 食物而正常用户的选择范围更宽。从那以后我每次拿到类似系统都会先检查用户画像字段的类型和取值范围再动手改算法。希望帮到你。本文还有配套的精品资源点击获取