Django+微信小程序在线点餐毕设源码:从环境搭建到接口联调全流程拆解
简介这是一套面向高校软件工程、计算机等专业本科毕业设计的完整项目源码主题为微信小程序在线点餐系统前端采用微信小程序原生框架后端基于Python-Django搭建适合正在准备毕设或需要前后端协同开发实战案例的学生参考。压缩包共约2000个文件整体18.39MB其中以1474个py后端逻辑文件、201个html模板、127个js脚本为主另含wxss、wxml小程序页面样式与结构文件以及css、json、txt等配置与说明文档目录结构清晰便于按模块检索。资源完整覆盖用户端与商家端两大模块包含菜品浏览、购物车、订单管理、数据统计等核心功能并涉及RESTful接口、MySQL存储与微信支付集成等实现思路。目前已有97人学习下载可作为毕设选题落地、代码拆解与功能扩展的实践参考。1. 从一份「在线点餐.zip」说起这套 Django 微信小程序毕设到底能不能跑起来每年到了毕设季后台被问得最多的一类问题就是拿到一份「前端微信小程序 后端 Python Django」的在线点餐源码包解压之后一脸懵不知道从哪下手。这份资源正好就是这样一个典型组合——小程序负责点餐界面、购物车、订单展示Django 负责菜品数据、订单落库和接口输出。它解决的不是「从零教你写代码」而是给你一套能跑通、能改、能写进论文的完整骨架。适合谁适合已经学过 Python 基础语法、知道 Django 大概长什么样、但没独立做过前后端联调项目的同学也适合想拿它当模板改造成外卖、食堂、奶茶店点单系统的开发者。下面我按「先跑起来、再拆结构、最后避坑」的顺序把这份包从头到尾捋一遍。2. 环境搭建与项目启动把 Django 后端先跑通2.1 为什么先跑后端而不是先开小程序很多人拿到包第一反应是打开微信开发者工具结果小程序一片报错就以为代码是坏的。其实这类项目的命脉在后端——小程序所有数据都靠 HTTP 请求从 Django 拿后端没起来前端必然是空的。所以正确顺序是先把 Django 跑在本地某个端口上用浏览器或 Postman 确认接口能返回 JSON再去调小程序。这也是我一般会坚持的习惯先让「数据源」活着再谈界面。环境上这份包是 Python Django 技术栈常见做法是用虚拟环境隔离依赖避免和你机器上其他项目的 Django 版本打架。Python 建议 3.8 及以上Django 版本以包内requirements.txt为准不要自己乱升级。# 创建并激活虚拟环境Windows 用 venv\Scripts\activate python -m venv venv source venv/bin/activate # 安装依赖版本以包内 requirements.txt 为准 pip install -r requirements.txt # 生成数据库表结构SQLite 一般已配置好无需额外装数据库 python manage.py makemigrations python manage.py migrate # 创建后台管理员账号用于录入菜品 python manage.py createsuperuser # 启动开发服务器默认 8000 端口 python manage.py runserver 0.0.0.0:8000逻辑说明makemigrations根据模型生成迁移文件migrate把表真正建到数据库里这两步顺序不能反。createsuperuser是给 Django 自带 admin 后台用的你后面录菜品、看订单都靠它。runserver后面跟0.0.0.0:8000是为了让同一局域网内的手机或开发者工具也能访问只写127.0.0.1的话手机连不上。参数上要留意settings.py里的ALLOWED_HOSTS本地调试可以临时写成[*]但仅限调试。数据库默认多半是 SQLite文件就在项目根目录删掉它再migrate就能重置数据这是最省事的「后悔药」。2.2 数据库配置与菜品数据录入跑起来之后浏览器打开http://127.0.0.1:8000/admin用刚才的超级用户登录你就能看到注册好的模型。在线点餐系统的核心表一般就几张菜品分类、菜品、订单、订单明细。先建分类再建菜品注意菜品要挂到分类下并且把图片字段传上去——小程序端展示靠的就是这个图片地址。# 典型的菜品模型结构以包内实际 models.py 为准 class Category(models.Model): name models.CharField(max_length50) # 分类名如「热菜」「饮品」 class Dish(models.Model): category models.ForeignKey(Category, on_deletemodels.CASCADE) # 外键关联分类 name models.CharField(max_length100) # 菜品名 price models.DecimalField(max_digits8, decimal_places2) # 价格用 Decimal 避免浮点误差 image models.ImageField(upload_todishes/) # 图片需配置 MEDIA 路径 is_active models.BooleanField(defaultTrue) # 是否上架下架不删数据逻辑说明ForeignKey加on_deletemodels.CASCADE表示分类删了下面菜品一起删毕设场景够用。价格用DecimalField而不是FloatField是因为金额用浮点会出现19.99存成19.989999的玄学问题对账时能让你抓狂。is_active是个实用字段菜品下架时置 False 而不是删记录历史订单才不会变成空数据。图片字段要能正常显示得在settings.py配MEDIA_URL和MEDIA_ROOT并在urls.py里加上静态文件服务否则 admin 传了图小程序拿到的地址是 404。这一步是新手翻车高发区务必确认。2.3 接口联调让小程序能拿到数据后端跑通、数据录好接下来确认接口。Django 这边通常用JsonResponse或 DRF 输出 JSON。你可以在浏览器直接访问接口地址比如http://127.0.0.1:8000/api/dishes/能看到一坨 JSON 就说明后端没问题。# 用 curl 快速验证接口返回比开小程序快得多 curl http://127.0.0.1:8000/api/dishes/如果返回 403 或 500先看 Django 控制台的报错栈八成是跨域或序列化字段写错。跨域问题在小程序里表现为请求失败但后端日志正常常见做法是装django-cors-headers把开发者工具的来源加进白名单。注意小程序正式环境要求 HTTPS 域名但本地调试可以在开发者工具里勾选「不校验合法域名」这是调试期专用上线前必须换真域名。3. 微信小程序端结构拆解页面、请求封装与购物车逻辑3.1 小程序目录结构与页面职责小程序端一般分几个核心页面首页菜品列表、菜品详情、购物车、订单确认、我的订单。目录上pages放页面utils放请求封装app.js管全局配置比如后端 baseUrl。拿到包先别急着改样式先找到app.js里配置后端地址的那一行把它改成你本机的 IP 加端口比如http://192.168.1.10:8000注意不能用localhost因为手机和电脑不是同一台设备。// app.js 里通常会有全局请求地址配置 App({ globalData: { baseUrl: http://192.168.1.10:8000, // 换成你电脑的局域网 IP cart: [] // 简易购物车也可放本地缓存 } })逻辑说明baseUrl用局域网 IP 是让真机预览时也能请求到后端。cart放全局数据是毕设常见简化做法但页面刷新会丢更稳的是用wx.setStorageSync存本地缓存。这里就涉及一个热词里常被搜的点——微信小程序设置缓存时间其实小程序缓存本身没有过期时间需要你自己存一个时间戳读取时比对过期就清掉。3.2 请求封装别在每个页面里裸写 wx.request一份能看的毕设代码请求一定是封装过的。裸写wx.request的后果是后端地址一改你要翻遍所有页面。封装后只改一处。// utils/request.js 统一封装请求 const app getApp() function request(url, method GET, data {}) { return new Promise((resolve, reject) { wx.request({ url: app.globalData.baseUrl url, // 拼接全局 baseUrl method: method, data: data, header: { content-type: application/json }, success: (res) { if (res.statusCode 200) { resolve(res.data) // 只把业务数据抛出去 } else { reject(res) // 非 200 交给调用方处理 } }, fail: (err) reject(err) // 网络层失败 }) }) } module.exports { request }逻辑说明用 Promise 包一层页面里就能用async/await写比回调地狱清爽。statusCode 200判断的是 HTTP 层成功业务层成功与否还得看返回体里的 code 字段这点要按包内约定来。header里如果后端要 token记得在这里统一带上别每个页面手动加。参数上method默认 GET下单这类写操作要传 POST并且后端要处理 CSRF——小程序请求不带 Django 的 CSRF token所以对应接口一般要加csrf_exempt这是本地联调必做的一步否则 POST 一律 403。3.3 购物车与下单流程的数据流转购物车逻辑是这类项目的重点也是答辩容易被问的地方。典型流程点「加入购物车」→ 数据进全局 cart 或本地缓存 → 购物车页渲染列表、算总价 → 点「去结算」→ 组装订单数据 POST 给后端 → 后端写订单表和明细表 → 返回订单号 → 小程序跳订单详情。// 加入购物车同菜品累加数量不同菜品追加 function addToCart(dish) { const cart wx.getStorageSync(cart) || [] const exist cart.find(item item.id dish.id) if (exist) { exist.count 1 // 已存在则数量 1 } else { cart.push({ ...dish, count: 1 }) // 新菜品初始数量 1 } wx.setStorageSync(cart, cart) // 写回本地缓存 }逻辑说明用find判断是否已在购物车避免同一菜品出现多行。count是数量总价 单价 × 数量再求和注意用整数分或保留两位小数处理别直接浮点相加。下单时把 cart 数组整个发给后端后端逐条写明细并计算订单总额存主表这样即使前端算错后端也有权威金额。这里有个常见坑下单成功后要清空购物车缓存否则用户返回再下单会重复。清空动作要放在后端返回成功之后不能提前清不然请求失败用户购物车就白攒了。4. 避坑与排查这份包最容易翻车的五个地方4.1 现象小程序请求全部失败后端日志却正常原因九成是跨域或域名校验。开发者工具默认校验合法域名而你用的是 IP 加端口不在白名单里。 解决开发阶段在开发者工具「详情 → 本地设置」勾选「不校验合法域名、web-view、TLS 版本以及 HTTPS 证书」后端装django-cors-headers把CORS_ALLOW_ALL_ORIGINS临时设为 True。上线前再收紧。4.2 现象admin 传了菜品图片小程序显示裂图原因MEDIA_URL没配或urls.py没加静态文件路由图片地址返回 404。 解决settings.py里设好MEDIA_URL /media/和MEDIA_ROOT并在项目urls.py末尾加static(settings.MEDIA_URL, document_rootsettings.MEDIA_ROOT)。注意这只在 DEBUGTrue 时生效生产环境要交给 Nginx。4.3 现象POST 下单接口返回 403 Forbidden原因Django 的 CSRF 保护拦截了不带 token 的请求而小程序请求天然没有这个 token。 解决给下单等写操作接口加csrf_exempt装饰器。这是本地联调的标准操作但要知道它的含义是「放弃这层防护」正式项目应改用 token 鉴权。4.4 现象真机预览能打开页面但数据加载不出来原因baseUrl写成了localhost或127.0.0.1真机访问的是手机自己不是你的电脑。 解决改成电脑的局域网 IP并确保手机和电脑连同一个 WiFi同时runserver要绑0.0.0.0ALLOWED_HOSTS要放行该 IP。4.5 现象订单金额出现 0.30000000000000004 这类小数原因用浮点数做金额运算二进制表示不精确。 解决金额统一用「分」为单位的整数存储和计算展示时再除以 100或者后端用Decimal前端计算也走整数。这是财务类功能的血泪经验别等答辩被老师问出来才改。5. 进阶改造与验证把毕设变成能讲清楚的作品跑通只是及格线想让这份包真正变成你的东西得会改、会验证。我一般会从三个方向动手。第一加一层简单的 token 鉴权。现在接口是裸奔的任何人知道地址就能拉数据。做法是登录接口返回一个 token小程序存本地缓存请求封装里统一带上后端写个装饰器校验。这样答辩时你能讲清楚「为什么需要鉴权」比只会 CRUD 高一个层次。第二把订单状态做成状态机。待支付、已支付、制作中、已完成、已取消用整数字段表示后端提供改状态的接口小程序「我的订单」按状态分 tab 展示。状态流转要限制合法路径比如已完成不能退回待支付这是业务逻辑的加分项。第三验证方法要成体系。别只靠手点写几个接口测试用例用 Django 自带的TestCase或直接 curl 脚本覆盖「正常下单」「库存不足」「重复提交」几种情况。# 用 Django 测试客户端验证下单接口的基本路径 from django.test import TestCase, Client class OrderTest(TestCase): def test_create_order(self): client Client() resp client.post(/api/order/, { items: [{id: 1, count: 2}] # 菜品 1 买 2 份 }, content_typeapplication/json) self.assertEqual(resp.status_code, 200) # 接口通 self.assertIn(order_no, resp.json()) # 返回了订单号逻辑说明Client模拟请求不用真开服务器就能测。断言分两层先看 HTTP 状态再看业务字段这样接口挂了能快速定位是路由问题还是逻辑问题。参数上content_type要和你接口实际接收的一致JSON 接口就写application/json写错会一直 415。还有个容易被忽略的点小程序端的「静音状态下播放音乐」这类细节如果点餐系统带背景音乐或提示音iOS 静音键会让wx.createInnerAudioContext不出声需要设置obeyMuteSwitch false这是平台差异安卓一般没这问题。类似的平台差异还有顶部导航栏高度不同机型不一样用wx.getSystemInfoSync().statusBarHeight动态算别写死。从那以后我每次拿到一份毕设源码都强制先跑后端、再验接口、最后开前端三步缺一不可顺序错了就是给自己找罪受。希望这份拆解能帮你把这份在线点餐包真正跑起来、改下去。本文还有配套的精品资源点击获取