简介:这份资源面向计算机相关专业毕业生与需要完成课程设计的开发者,提供一套可直接参考的「家庭大厨」微信小程序完整项目方案,采用微信小程序+Django+Vue+MySQL的前后端分离架构,适合作为毕业设计选题或全栈练手项目。压缩包共718个文件,约44.78MB,涵盖129个Vue组件、82个JavaScript脚本、55个Python后端文件、161个SVG与125个PNG图标资源,以及SQL数据库脚本、毕业论文文档和视频教程,另附安装、运行、构建等批处理脚本,便于快速部署与二次开发。系统包含个人中心、用户管理、店铺管理、菜品信息与分类管理、购买菜品、订单行及系统管理等模块,用户与店铺均可通过小程序注册登录并操作菜品与订单。目前已有194人学习下载,读者可从中获取完整源码、数据库脚本、论文参考与视频讲解,理清前后端分离项目的目录结构与开发思路。1. 家庭大厨小程序:一套前后端分离的毕设项目,到底该怎么跑起来很多同学做毕业设计时,选题方向定了“家庭大厨”这类菜谱分享与私厨预约的小程序,但真正动手才发现,难点从来不是写一个页面,而是把微信小程序、Django 后端、Vue 管理后台和 MySQL 数据库这四块拼成一个能跑通、能演示、能写进论文的系统。这套组合在毕设里非常常见,原因也很直接:小程序负责用户端体验,Django 提供 REST 接口和业务逻辑,Vue 做管理端的数据看板与内容审核,MySQL 存菜谱、订单、用户和评论。前后端分离意味着接口先行,前端不关心后端怎么实现,后端也不关心页面长什么样。适合谁?适合已经学过 Python 基础、了解 Vue 组件概念、能看懂小程序官方文档的本科生。如果你正卡在“源码拿到手却跑不起来”或者“论文写不出技术章节”的阶段,下面这套从环境到接口再到避坑的路径,就是按一线调试顺序整理的。2. 环境搭建与项目结构:把四块拼图先对上号2.1 后端 Django 环境与依赖安装拿到源码后不要急着改代码,先把后端跑起来。我一般会新建一个干净的虚拟环境,避免和系统里其他项目的包版本打架。假设源码根目录下有backend文件夹,里面是 Django 工程。# 创建虚拟环境,Python 版本建议 3.8 到 3.10,太新反而容易遇到依赖不兼容 python -m venv venv # 激活虚拟环境,Windows 用 venv\Scripts\activate,macOS/Linux 用 source venv/bin/activate source venv/bin/activate # 安装依赖,通常源码里会带 requirements.txt pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple # 如果 requirements.txt 缺失,常见核心依赖如下 pip install django djangorestframework django-cors-headers mysqlclient pillow这里有几个参数需要留意。django-cors-headers是前后端分离的刚需,因为小程序和 Vue 开发服务器跑在不同端口,浏览器和小程序都会做跨域检查。mysqlclient是 Python 连接 MySQL 的驱动,Windows 上如果安装失败,可以换成pymysql并在__init__.py里补一行pymysql.install_as_MySQLdb()。pillow用于处理菜品图片上传,家庭大厨项目里几乎一定会用到。安装完成后,进入backend目录,找到settings.py,把数据库配置改成你本地的 MySQL 连接信息。常见配置如下:DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'family_chef', # 数据库名,和后面导入的脚本保持一致 'USER': 'root', # 本地开发通常用 root 'PASSWORD': 'your_password', 'HOST': '127.0.0.1', 'PORT': '3306', 'OPTIONS': {'charset': 'utf8mb4'}, # 支持 emoji,评论里经常出现 } }utf8mb4这个字符集不要省,家庭大厨项目的评论区和菜谱描述里很容易出现特殊符号,用utf8会在插入时报错。改完数据库配置后,先别急着migrate,因为源码通常附带.sql数据库脚本,直接导入比让 Django 自己建表更稳妥。2.2 数据库脚本导入与初始数据检查数据库脚本一般放在源码的db或sql文件夹里,文件名可能是family_chef.sql。导入前先建库:# 登录 MySQL,输入密码 mysql -u root -p # 创建数据库,字符集和排序规则要和 Django 配置一致 CREATE DATABASE family_chef DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; # 退出 MySQL exit; # 在命令行导入脚本,注意路径替换成实际文件位置 mysql -u root -p family_chef < /path/to/family_chef.sql导入完成后,回到 Django 项目,执行迁移和启动命令:python manage.py makemigrations python manage.py migrate python manage.py runserver 0.0.0.0:80000.0.0.0:8000这个写法是为了让同一局域网内的手机也能访问后端接口,方便真机调试小程序。如果只用开发者工具模拟器,127.0.0.1:8000就够了。启动后访问http://127.0.0.1:8000/admin,如果能出现 Django 管理登录页,说明后端基本通了。初始账号密码通常在数据库脚本的auth_user表里,或者源码说明里会写,常见的是admin/admin123这类,登录后记得改掉。2.3 Vue 管理端启动与接口代理配置Vue 管理端一般放在admin或vue-admin目录。先确认package.json里的依赖,然后安装并启动:# 进入 Vue 项目目录 cd admin # 安装依赖,网络慢可以换淘宝源 npm install --registry=https://registry.npmmirror.com # 启动开发服务器 npm run serve启动后浏览器会打开一个本地地址,通常是http://localhost:8080。这时候打开浏览器控制台,大概率会看到接口请求跨域报错。解决办法是在 Vue 项目根目录新建或修改vue.config.js:module.exports = { devServer: { port: 8080, proxy: { '/api': { target: 'http://127.0.0.1:8000', // Django 后端地址 changeOrigin: true, pathRewrite: { '^/api': '/api' } // 保持接口前缀一致 } } } }changeOrigin设为true是为了让后端收到的请求头里的 Host 和实际后端地址一致,避免 Django 的ALLOWED_HOSTS拦截。pathRewrite这里看起来没变化,但有些项目后端接口不带/api前缀,就需要在这里去掉。改完配置要重启 Vue 开发服务器,热更新不会让代理配置生效。2.4 小程序端配置与真机预览小程序端用微信开发者工具打开miniprogram或wxapp目录。第一件事是改app.js或config.js里的接口基地址:// 本地调试用 127.0.0.1,真机预览要改成电脑的局域网 IP const BASE_URL = 'http://192.168.1.100:8000/api'; // 请求封装示例 const request = (url, method = 'GET', data = {}) => { return new Promise((resolve, reject) => { wx.request({ url: BASE_URL + url, method, data, header: { 'content-type': 'application/json' }, success: res => resolve(res.data), fail: err => reject(err) }); }); };真机预览时,手机和电脑必须在同一个 Wi-Fi 下,且电脑防火墙要放行 8000 端口。微信开发者工具里还要在“详情-本地设置”中勾选“不校验合法域名”,否则http请求会被拦截。这一步是新手最容易卡住的地方,现象是模拟器正常、真机白屏或请求失败。3. 核心接口与数据模型:菜谱、订单、评论怎么串起来3.1 菜谱模型设计与图片上传接口家庭大厨的核心数据是菜谱。一个合理的模型至少包含菜名、分类、食材、步骤、封面图、作者、发布时间和浏览量。Django 里通常这样定义:class Recipe(models.Model): title = models.CharField(max_length=100, verbose_name='菜名') category = models.ForeignKey('Category', on_delete=models.SET_NULL, null=True) ingredients = models.TextField(verbose_name='食材清单') steps = models.TextField(verbose_name='制作步骤') cover = models.ImageField(upload_to='recipes/%Y/%m/', verbose_name='封面图') author = models.ForeignKey(User, on_delete=models.CASCADE) views = models.PositiveIntegerField(default=0) created_at = models.DateTimeField(auto_now_add=True) class Meta: ordering = ['-created_at']upload_to='recipes/%Y/%m/'会按年月自动分目录,避免所有图片堆在一个文件夹里。on_delete=models.SET_NULL表示分类被删除时菜谱不跟着删,只把分类置空,这对内容管理更友好。图片上传接口用 DRF 的ModelViewSet配合MultiPartParser就能实现,前端小程序用wx.uploadFile上传,注意name字段要和后端接收的字段名一致,通常是cover。3.2 订单状态流转与前后端字段对齐私厨预约订单是另一个核心。订单状态一般有:待确认、已确认、制作中、已完成、已取消。后端用choices约束状态值:class Order(models.Model): STATUS_CHOICES = ( ('pending', '待确认'), ('confirmed', '已确认'), ('cooking', '制作中'), ('done', '已完成'), ('cancelled', '已取消'), ) user = models.ForeignKey(User, on_delete=models.CASCADE) recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE) status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending') appointment = models.DateTimeField(verbose_name='预约时间') remark = models.CharField(max_length=200, blank=True)前后端字段对齐是血泪经验。小程序里习惯用驼峰appointmentTime,Django 默认返回蛇形appointment,如果不做转换,前端拿到的就是undefined。常见做法是在 DRF 序列化器里用source指定,或者统一在设置里开启CamelCaseJSONRenderer。我一般倾向于后端保持蛇形,前端在请求封装层做一次转换,这样后端代码更符合 Python 习惯。3.3 评论与评分接口的防重复提交评论接口看起来简单,但很容易被重复提交。用户点一次按钮,网络慢的时候可能连点多次,数据库里就会出现多条相同评论。解决办法有两个层面:前端按钮点击后立即置灰,后端在创建前做一次短时间窗口的去重查询。from django.utils import timezone from datetime import timedelta class CommentCreateView(APIView): def post(self, request): user = request.user recipe_id = request.data.get('recipe') content = request.data.get('content', '').strip() # 10 秒内同一用户对同一菜谱的相同内容视为重复 recent = Comment.objects.filter( user=user, recipe_id=recipe_id, content=content, created_at__gte=timezone.now() - timedelta(seconds=10) ).exists() if recent: return Response({'code': 400, 'msg': '请勿重复提交'}) Comment.objects.create(user=user, recipe_id=recipe_id, content=content) return Response({'code': 200, 'msg': 'ok'})timedelta(seconds=10)这个窗口不要设太大,否则用户正常修改后重新提交也会被拦。评分字段建议单独一张表,和评论分开,因为评分需要聚合计算平均分,混在评论表里查询会越来越慢。4. 避坑与常见问题:跑不起来时先查这几处4.1 跨域报错但配置明明写了现象:Vue 控制台报Access-Control-Allow-Origin缺失,但django-cors-headers已经安装。原因通常是中间件顺序不对。corsheaders.middleware.CorsMiddleware必须放在CommonMiddleware之前,否则响应头会被覆盖。解决:检查MIDDLEWARE列表,把 CorsMiddleware 提到最上面几行,并确认CORS_ALLOW_ALL_ORIGINS = True在开发阶段是开启的。4.2 小程序真机请求失败但模拟器正常现象:开发者工具里接口正常,手机预览时所有请求都失败。原因有两个:一是基地址还是127.0.0.1,手机访问不到电脑;二是电脑防火墙拦了 8000 端口。解决:把基地址改成电脑局域网 IP,用ipconfig或ifconfig查看;然后在防火墙入站规则里放行 8000 端口,或者临时关闭防火墙测试。4.3 数据库导入后中文乱码现象:菜谱标题和评论显示成问号或乱码。原因:导入时客户端字符集不是utf8mb4。解决:导入命令前加--default-character-set=utf8mb4,即mysql -u root -p --default-character-set=utf8mb4 family_chef < xxx.sql。如果已经导入乱了,删库重建再导一次,比逐条修数据快得多。4.4 图片上传成功但前端显示裂图现象:后端返回了图片 URL,小程序里<image>标签却加载不出来。原因:Django 开发环境下没有配置媒体文件的访问路由。解决:在urls.py里加static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT),并确认MEDIA_URL和MEDIA_ROOT已设置。另外小程序里图片 URL 必须是完整地址,不能是相对路径。4.5 迁移时提示表已存在现象:执行migrate时报Table 'xxx' already exists。原因:数据库脚本已经建了表,但 Django 的迁移记录表django_migrations里没有对应记录。解决:不要直接删表,先用python manage.py migrate --fake把对应迁移标记为已执行,或者手动在django_migrations表里插入记录。更稳妥的做法是导入脚本后,只对没有的表执行迁移。5. 论文与演示的收尾技巧:让系统看起来更完整5.1 用接口文档撑起论文的技术章节毕业论文里最容易被导师挑毛病的是“技术实现”部分写得太虚。一个具体技巧是:把 DRF 自动生成的接口文档截图放进论文,配合请求参数和返回示例。DRF 自带coreapi或drf-spectacular,配置后访问/docs就能看到所有接口。论文里可以写“系统共设计 18 个 RESTful 接口,覆盖用户认证、菜谱管理、订单流转和评论互动”,这比空泛描述有说服力。5.2 演示视频的录制顺序录制演示视频时,不要从登录页开始慢慢点。我一般按这个顺序:先展示小程序端首页菜谱列表和详情,再演示预约下单,然后切到 Vue 管理后台展示订单审核和菜谱上架,最后回到小程序看订单状态变化。整个过程控制在 3 到 5 分钟,提前把测试数据准备好,避免现场等接口返回。视频里不要出现真实姓名和学校信息,用测试账号。5.3 源码二次开发的最小改动点如果想让系统看起来不那么像模板,改三个地方就够了:一是小程序首页的配色和轮播图,换成自己拍的菜品图;二是管理后台的标题和 Logo;三是在菜谱详情页加一个“相似推荐”模块,用简单的分类匹配实现,不需要上推荐算法。这三个改动成本低,但在答辩时能明显提升“自主完成度”的观感。5.4 数据库备份与恢复的保命习惯答辩前一周,每天做一次数据库备份。命令很简单:mysqldump -u root -p --default-character-set=utf8mb4 family_chef > backup_$(date +%Y%m%d).sql恢复的时候用mysql -u root -p family_chef < backup_xxx.sql。这个习惯救过我一次,当时演示前一天误删了一张核心表,靠备份十分钟就恢复了。不要等到出事才后悔没有后悔药。5.5 一个容易被忽略的细节:时区Django 默认时区是 UTC,小程序和 Vue 显示的时间会差 8 小时。在settings.py里改TIME_ZONE = 'Asia/Shanghai'和USE_TZ = False,这样数据库里存的就是本地时间,前端不用再做转换。这个坑在订单预约时间上特别明显,用户选了下午 3 点,后端存成早上 7 点,演示时一眼就能看出来。希望帮到你。本文还有配套的精品资源,点击获取
简介:这份资源面向计算机相关专业毕业生与需要完成课程设计的开发者,提供一套可直接参考的「家庭大厨」微信小程序完整项目方案,采用微信小程序+Django+Vue+MySQL的前后端分离架构,适合作为毕业设计选题或全栈练手项目。压缩包共718个文件,约44.78MB,涵盖129个Vue组件、82个JavaScript脚本、55个Python后端文件、161个SVG与125个PNG图标资源,以及SQL数据库脚本、毕业论文文档和视频教程,另附安装、运行、构建等批处理脚本,便于快速部署与二次开发。系统包含个人中心、用户管理、店铺管理、菜品信息与分类管理、购买菜品、订单行及系统管理等模块,用户与店铺均可通过小程序注册登录并操作菜品与订单。目前已有194人学习下载,读者可从中获取完整源码、数据库脚本、论文参考与视频讲解,理清前后端分离项目的目录结构与开发思路。1. 家庭大厨小程序:一套前后端分离的毕设项目,到底该怎么跑起来很多同学做毕业设计时,选题方向定了“家庭大厨”这类菜谱分享与私厨预约的小程序,但真正动手才发现,难点从来不是写一个页面,而是把微信小程序、Django 后端、Vue 管理后台和 MySQL 数据库这四块拼成一个能跑通、能演示、能写进论文的系统。这套组合在毕设里非常常见,原因也很直接:小程序负责用户端体验,Django 提供 REST 接口和业务逻辑,Vue 做管理端的数据看板与内容审核,MySQL 存菜谱、订单、用户和评论。前后端分离意味着接口先行,前端不关心后端怎么实现,后端也不关心页面长什么样。适合谁?适合已经学过 Python 基础、了解 Vue 组件概念、能看懂小程序官方文档的本科生。如果你正卡在“源码拿到手却跑不起来”或者“论文写不出技术章节”的阶段,下面这套从环境到接口再到避坑的路径,就是按一线调试顺序整理的。2. 环境搭建与项目结构:把四块拼图先对上号2.1 后端 Django 环境与依赖安装拿到源码后不要急着改代码,先把后端跑起来。我一般会新建一个干净的虚拟环境,避免和系统里其他项目的包版本打架。假设源码根目录下有backend文件夹,里面是 Django 工程。# 创建虚拟环境,Python 版本建议 3.8 到 3.10,太新反而容易遇到依赖不兼容 python -m venv venv # 激活虚拟环境,Windows 用 venv\Scripts\activate,macOS/Linux 用 source venv/bin/activate source venv/bin/activate # 安装依赖,通常源码里会带 requirements.txt pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple # 如果 requirements.txt 缺失,常见核心依赖如下 pip install django djangorestframework django-cors-headers mysqlclient pillow这里有几个参数需要留意。django-cors-headers是前后端分离的刚需,因为小程序和 Vue 开发服务器跑在不同端口,浏览器和小程序都会做跨域检查。mysqlclient是 Python 连接 MySQL 的驱动,Windows 上如果安装失败,可以换成pymysql并在__init__.py里补一行pymysql.install_as_MySQLdb()。pillow用于处理菜品图片上传,家庭大厨项目里几乎一定会用到。安装完成后,进入backend目录,找到settings.py,把数据库配置改成你本地的 MySQL 连接信息。常见配置如下:DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'family_chef', # 数据库名,和后面导入的脚本保持一致 'USER': 'root', # 本地开发通常用 root 'PASSWORD': 'your_password', 'HOST': '127.0.0.1', 'PORT': '3306', 'OPTIONS': {'charset': 'utf8mb4'}, # 支持 emoji,评论里经常出现 } }utf8mb4这个字符集不要省,家庭大厨项目的评论区和菜谱描述里很容易出现特殊符号,用utf8会在插入时报错。改完数据库配置后,先别急着migrate,因为源码通常附带.sql数据库脚本,直接导入比让 Django 自己建表更稳妥。2.2 数据库脚本导入与初始数据检查数据库脚本一般放在源码的db或sql文件夹里,文件名可能是family_chef.sql。导入前先建库:# 登录 MySQL,输入密码 mysql -u root -p # 创建数据库,字符集和排序规则要和 Django 配置一致 CREATE DATABASE family_chef DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; # 退出 MySQL exit; # 在命令行导入脚本,注意路径替换成实际文件位置 mysql -u root -p family_chef < /path/to/family_chef.sql导入完成后,回到 Django 项目,执行迁移和启动命令:python manage.py makemigrations python manage.py migrate python manage.py runserver 0.0.0.0:80000.0.0.0:8000这个写法是为了让同一局域网内的手机也能访问后端接口,方便真机调试小程序。如果只用开发者工具模拟器,127.0.0.1:8000就够了。启动后访问http://127.0.0.1:8000/admin,如果能出现 Django 管理登录页,说明后端基本通了。初始账号密码通常在数据库脚本的auth_user表里,或者源码说明里会写,常见的是admin/admin123这类,登录后记得改掉。2.3 Vue 管理端启动与接口代理配置Vue 管理端一般放在admin或vue-admin目录。先确认package.json里的依赖,然后安装并启动:# 进入 Vue 项目目录 cd admin # 安装依赖,网络慢可以换淘宝源 npm install --registry=https://registry.npmmirror.com # 启动开发服务器 npm run serve启动后浏览器会打开一个本地地址,通常是http://localhost:8080。这时候打开浏览器控制台,大概率会看到接口请求跨域报错。解决办法是在 Vue 项目根目录新建或修改vue.config.js:module.exports = { devServer: { port: 8080, proxy: { '/api': { target: 'http://127.0.0.1:8000', // Django 后端地址 changeOrigin: true, pathRewrite: { '^/api': '/api' } // 保持接口前缀一致 } } } }changeOrigin设为true是为了让后端收到的请求头里的 Host 和实际后端地址一致,避免 Django 的ALLOWED_HOSTS拦截。pathRewrite这里看起来没变化,但有些项目后端接口不带/api前缀,就需要在这里去掉。改完配置要重启 Vue 开发服务器,热更新不会让代理配置生效。2.4 小程序端配置与真机预览小程序端用微信开发者工具打开miniprogram或wxapp目录。第一件事是改app.js或config.js里的接口基地址:// 本地调试用 127.0.0.1,真机预览要改成电脑的局域网 IP const BASE_URL = 'http://192.168.1.100:8000/api'; // 请求封装示例 const request = (url, method = 'GET', data = {}) => { return new Promise((resolve, reject) => { wx.request({ url: BASE_URL + url, method, data, header: { 'content-type': 'application/json' }, success: res => resolve(res.data), fail: err => reject(err) }); }); };真机预览时,手机和电脑必须在同一个 Wi-Fi 下,且电脑防火墙要放行 8000 端口。微信开发者工具里还要在“详情-本地设置”中勾选“不校验合法域名”,否则http请求会被拦截。这一步是新手最容易卡住的地方,现象是模拟器正常、真机白屏或请求失败。3. 核心接口与数据模型:菜谱、订单、评论怎么串起来3.1 菜谱模型设计与图片上传接口家庭大厨的核心数据是菜谱。一个合理的模型至少包含菜名、分类、食材、步骤、封面图、作者、发布时间和浏览量。Django 里通常这样定义:class Recipe(models.Model): title = models.CharField(max_length=100, verbose_name='菜名') category = models.ForeignKey('Category', on_delete=models.SET_NULL, null=True) ingredients = models.TextField(verbose_name='食材清单') steps = models.TextField(verbose_name='制作步骤') cover = models.ImageField(upload_to='recipes/%Y/%m/', verbose_name='封面图') author = models.ForeignKey(User, on_delete=models.CASCADE) views = models.PositiveIntegerField(default=0) created_at = models.DateTimeField(auto_now_add=True) class Meta: ordering = ['-created_at']upload_to='recipes/%Y/%m/'会按年月自动分目录,避免所有图片堆在一个文件夹里。on_delete=models.SET_NULL表示分类被删除时菜谱不跟着删,只把分类置空,这对内容管理更友好。图片上传接口用 DRF 的ModelViewSet配合MultiPartParser就能实现,前端小程序用wx.uploadFile上传,注意name字段要和后端接收的字段名一致,通常是cover。3.2 订单状态流转与前后端字段对齐私厨预约订单是另一个核心。订单状态一般有:待确认、已确认、制作中、已完成、已取消。后端用choices约束状态值:class Order(models.Model): STATUS_CHOICES = ( ('pending', '待确认'), ('confirmed', '已确认'), ('cooking', '制作中'), ('done', '已完成'), ('cancelled', '已取消'), ) user = models.ForeignKey(User, on_delete=models.CASCADE) recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE) status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending') appointment = models.DateTimeField(verbose_name='预约时间') remark = models.CharField(max_length=200, blank=True)前后端字段对齐是血泪经验。小程序里习惯用驼峰appointmentTime,Django 默认返回蛇形appointment,如果不做转换,前端拿到的就是undefined。常见做法是在 DRF 序列化器里用source指定,或者统一在设置里开启CamelCaseJSONRenderer。我一般倾向于后端保持蛇形,前端在请求封装层做一次转换,这样后端代码更符合 Python 习惯。3.3 评论与评分接口的防重复提交评论接口看起来简单,但很容易被重复提交。用户点一次按钮,网络慢的时候可能连点多次,数据库里就会出现多条相同评论。解决办法有两个层面:前端按钮点击后立即置灰,后端在创建前做一次短时间窗口的去重查询。from django.utils import timezone from datetime import timedelta class CommentCreateView(APIView): def post(self, request): user = request.user recipe_id = request.data.get('recipe') content = request.data.get('content', '').strip() # 10 秒内同一用户对同一菜谱的相同内容视为重复 recent = Comment.objects.filter( user=user, recipe_id=recipe_id, content=content, created_at__gte=timezone.now() - timedelta(seconds=10) ).exists() if recent: return Response({'code': 400, 'msg': '请勿重复提交'}) Comment.objects.create(user=user, recipe_id=recipe_id, content=content) return Response({'code': 200, 'msg': 'ok'})timedelta(seconds=10)这个窗口不要设太大,否则用户正常修改后重新提交也会被拦。评分字段建议单独一张表,和评论分开,因为评分需要聚合计算平均分,混在评论表里查询会越来越慢。4. 避坑与常见问题:跑不起来时先查这几处4.1 跨域报错但配置明明写了现象:Vue 控制台报Access-Control-Allow-Origin缺失,但django-cors-headers已经安装。原因通常是中间件顺序不对。corsheaders.middleware.CorsMiddleware必须放在CommonMiddleware之前,否则响应头会被覆盖。解决:检查MIDDLEWARE列表,把 CorsMiddleware 提到最上面几行,并确认CORS_ALLOW_ALL_ORIGINS = True在开发阶段是开启的。4.2 小程序真机请求失败但模拟器正常现象:开发者工具里接口正常,手机预览时所有请求都失败。原因有两个:一是基地址还是127.0.0.1,手机访问不到电脑;二是电脑防火墙拦了 8000 端口。解决:把基地址改成电脑局域网 IP,用ipconfig或ifconfig查看;然后在防火墙入站规则里放行 8000 端口,或者临时关闭防火墙测试。4.3 数据库导入后中文乱码现象:菜谱标题和评论显示成问号或乱码。原因:导入时客户端字符集不是utf8mb4。解决:导入命令前加--default-character-set=utf8mb4,即mysql -u root -p --default-character-set=utf8mb4 family_chef < xxx.sql。如果已经导入乱了,删库重建再导一次,比逐条修数据快得多。4.4 图片上传成功但前端显示裂图现象:后端返回了图片 URL,小程序里<image>标签却加载不出来。原因:Django 开发环境下没有配置媒体文件的访问路由。解决:在urls.py里加static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT),并确认MEDIA_URL和MEDIA_ROOT已设置。另外小程序里图片 URL 必须是完整地址,不能是相对路径。4.5 迁移时提示表已存在现象:执行migrate时报Table 'xxx' already exists。原因:数据库脚本已经建了表,但 Django 的迁移记录表django_migrations里没有对应记录。解决:不要直接删表,先用python manage.py migrate --fake把对应迁移标记为已执行,或者手动在django_migrations表里插入记录。更稳妥的做法是导入脚本后,只对没有的表执行迁移。5. 论文与演示的收尾技巧:让系统看起来更完整5.1 用接口文档撑起论文的技术章节毕业论文里最容易被导师挑毛病的是“技术实现”部分写得太虚。一个具体技巧是:把 DRF 自动生成的接口文档截图放进论文,配合请求参数和返回示例。DRF 自带coreapi或drf-spectacular,配置后访问/docs就能看到所有接口。论文里可以写“系统共设计 18 个 RESTful 接口,覆盖用户认证、菜谱管理、订单流转和评论互动”,这比空泛描述有说服力。5.2 演示视频的录制顺序录制演示视频时,不要从登录页开始慢慢点。我一般按这个顺序:先展示小程序端首页菜谱列表和详情,再演示预约下单,然后切到 Vue 管理后台展示订单审核和菜谱上架,最后回到小程序看订单状态变化。整个过程控制在 3 到 5 分钟,提前把测试数据准备好,避免现场等接口返回。视频里不要出现真实姓名和学校信息,用测试账号。5.3 源码二次开发的最小改动点如果想让系统看起来不那么像模板,改三个地方就够了:一是小程序首页的配色和轮播图,换成自己拍的菜品图;二是管理后台的标题和 Logo;三是在菜谱详情页加一个“相似推荐”模块,用简单的分类匹配实现,不需要上推荐算法。这三个改动成本低,但在答辩时能明显提升“自主完成度”的观感。5.4 数据库备份与恢复的保命习惯答辩前一周,每天做一次数据库备份。命令很简单:mysqldump -u root -p --default-character-set=utf8mb4 family_chef > backup_$(date +%Y%m%d).sql恢复的时候用mysql -u root -p family_chef < backup_xxx.sql。这个习惯救过我一次,当时演示前一天误删了一张核心表,靠备份十分钟就恢复了。不要等到出事才后悔没有后悔药。5.5 一个容易被忽略的细节:时区Django 默认时区是 UTC,小程序和 Vue 显示的时间会差 8 小时。在settings.py里改TIME_ZONE = 'Asia/Shanghai'和USE_TZ = False,这样数据库里存的就是本地时间,前端不用再做转换。这个坑在订单预约时间上特别明显,用户选了下午 3 点,后端存成早上 7 点,演示时一眼就能看出来。希望帮到你。本文还有配套的精品资源,点击获取