news 2026/9/30 3:54:09

Django+Vue+Echarts+LSTM:京东茶叶数据可视化与销量预测系统实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Django+Vue+Echarts+LSTM:京东茶叶数据可视化与销量预测系统实战

毕设做完了,从开题报告到最后的答辩PPT,我把整套东西都跑通了一遍。这项目名称挺长——“京东茶叶数据可视化分析系统与实现”,后面还缀着“大数据深度学习算法毕设毕业设计项目Django+Vue”,光看这串字就知道老师想让你同时秀出前后端、可视化、算法这三板斧。这篇文章我不打算复述教科书,就按我实际做这个项目的路线,聊聊怎么拆解需求、选型、落地,以及那些文档里不会写的坑。如果你正准备做类似题目,或者正在为技术选型犹豫,这篇应该能让你少走不少弯路。

1. 项目整体设计与思路拆解

1.1 需求拆解:毕设题目里隐藏的评分点

先别急着写代码,把题目拆开看。这题目其实就四个关键词:京东茶叶数据、数据可视化、大数据、深度学习算法。再配上Django+Vue这个技术栈组合,整个项目的基本盘就出来了。

“京东茶叶数据”意味着你的数据源要跟电商茶叶销售挂钩,那就是商品信息、价格、销量、评论、店铺、品牌这些维度。你需要一套爬虫或者现成数据集来做支撑,不然光造数据也能做,但答辩时容易被追问数据来源,所以最好是真实爬下来的。

“数据可视化”是核心交付物,Echarts基本是标配。你需要把清洗完的数据变成折线图、柱状图、饼图、热力图、词云等,让看的人能直观理解茶叶市场的价格分布、品牌份额、销量趋势。

“大数据”听起来唬人,但毕设层面不会真让你搭Hadoop集群。Django ORM配合Pandas做数据清洗和聚合,只要数据量能到几万条以上,再设计几个合理的统计口径,完全够交代。要是你愿意,塞一个Redis缓存和异步任务进去,在文档里写“高并发查询优化”,档次瞬间不一样。

“深度学习算法”是加分项,也是很多同学最怕的部分。这里别上去就整Transformer,茶叶电商场景里,LSTM做销量预测或者Bert做评论情感分析都是成熟路线。我选的是销量预测,因为跟“数据分析系统”贴合度更高——用户可以选某个茶叶品类,看历史销量曲线和未来7天预测值。

技术栈Django+Vue不用多解释。Django做RESTful API后端,Vue做单页前端,中间用Axios通信。这套组合在毕设里非常常见,因为你既有“框架使用深度”可写,又有“前后端分离架构”可吹,工作量完全可控。

1.2 架构选型:为什么是Django + Vue而不是别的

选Django的原因很实际:自带Admin后台、ORM、认证系统,开发效率高。毕设开发周期一般两三个月,你用Spring Boot可能光配环境就要一周,Django半小时就能把项目和App建好。而且Django的ORM在数据聚合查询上写起来非常直观,后面做统计接口能省大量SQL调试时间。

Vue这边,我建议直接用Vue 3 + Vite,别再用Vue 2 + Webpack了。Vue 3的Composition API写业务逻辑更清爽,Vite在开发时热更新快得不是一点半点。不过要注意,很多老教程还是Vue 2的写法,你得自己过滤,别混着看。

组件库方面,Element Plus是首选,表格、表单、布局开箱即用。图表一定用Echarts,而且用echarts-vue3这个封装或者直接原生Echarts都行。我个人倾向于直接引入原生Echarts再自己封装一个Chart组件,自由度更高,答辩时也更好讲——你能说出来每个配置项是干嘛的,而不是只会套模板。

后端接口设计遵循RESTful规范:/api/products/、/api/statistics/price_trend/、/api/statistics/brand_share/、/api/predict/sales/这样一条路下来。Django Rest Framework(DRF)提供serializer和viewset,写起来非常顺手,权限验证直接用DRF的TokenAuthentication就行。

2. 核心细节解析与实操要点

2.1 数据层设计:从爬虫到数据清洗的完整流程

数据是整个系统的地基。我当时爬的是京东茶叶类目下的商品列表,包括商品名、价格、评论数、店铺名称、品牌、上下架时间等字段。这里有两个关键点:

第一,爬虫要控制频率。京东反爬不算凶,但短时间大量请求会被封IP。我用的是requests加fake_useragent随机切换UA,同时设置了每请求之间随机睡2-5秒。单线程爬了大概一天多,拿到两万多条数据。有些人用Scrapy,其实这类中小规模任务requests就够了,Scrapy反而重。

第二,清洗比爬取更花时间。原始数据大概率有这些问题:价格字段里混着“¥”符号和促销文案、评论数写的是“10万+”这种格式化文本、品牌字段为空、商品名里全是营销噱头需要正则提取品类。我把清洗脚本写在django的管理命令里(management/commands/clean_data.py),这样能复用项目环境和ORM,清洗结果直接入库,不用中间倒腾CSV。

清洗流程大概是:用Pandas读原始数据,去重、删空、正则提取数值字段、按价格区间打标签、解析评论数单位。然后按sku维度存到Product表,再按品牌、品类维度生成聚合统计表存到Redis里做冷数据缓存。这一步非常加分,因为我不仅把数据清了,还做了数据分层的设计——原始层、明细层、统计层,答辩时就可以跟“大数据架构”扯上关系了。

2.2 Django ORM与序列化:聚合查询不要每次现算

很多新手犯的错是前端需要什么数据就实时查什么,量小没事,量一大接口就卡。我这边统计页面的数据绝大多数来自预计算:

  • 品牌销售占比:定时任务(APScheduler或Celery beat)每天凌晨跑一次,按品牌聚合销量存储到BrandStat模型。
  • 价格区间分布:商品入库时直接按价格档位写入PriceBucketStat。
  • 日销量趋势:从订单表(模拟生成或爬取导出)按日期聚合,存入DailySalesStat。

这样页面展示时,ORM查询变成简单的BrandStat.objects.order_by('-sales'),一次查询直接返回,不用跑聚合。Django ORM的values().annotate()虽然也很快,但每次都在几万行上跑聚合,压力还是大。我们设计成“预计算+定时刷新”的模式,页面秒开,体验好,架构上也说得过去。

序列化这一步,DRF的ModelSerializer够用。给它加一个get_price_range之类的SerializerMethodField,前端要的展示字段就能灵活拼接。要注意的是,接口返回的字段不是数据库字段的直出,前后端之间需要定一个DTO(Data Transfer Object),DRF里就是Serializer。比如前端要显示“价格标签”,你在Serializer里算好,而不是让前端拿原始价格自己映射,这样前端更薄,逻辑也集中在后端。

2.3 Vue前端架构:组件拆分与状态管理

前端看上去页面不多——总览、品类分析、品牌分析、预测——但拆组件时一定要按业务切,而不是按页面切。比如价格区间柱状图、品牌占比环形图、销量趋势折线图这三个图表组件,可能在总览和品类分析里都出现,那就抽成PriceDistributionChart.vue、BrandShareChart.vue、SalesTrendChart.vue,各自负责自己的数据和渲染。

每个图表组件内部逻辑是:props传入查询条件(比如selectedCategory),组件watch这个props变化后,调用API拉数据,再setOption渲染图表。这个模式简单清晰,不用Vuex,因为大部分数据是组件通过props共享的。只有当登录用户信息和全局筛选条件跨多页面共享时才引入Pinia(Vue 3推荐,比Vuex轻量)。

一个很值得注意的细节是,Echarts在Vue里必须处理销毁逻辑:组件卸载时调用chart.dispose(),否则页面反复切换时会有内存泄漏——表现就是图表越切越卡、控制台报大量警告。很多人卡在这个坑半天,其实就是在onUnmounted里少写了几行代码。

3. 实操过程与核心环节实现

3.1 环境搭建与项目初始化:一步步来

后端环境:Python 3.10,Django 4.2,DRF 3.14,Pandas,APScheduler。建议用虚拟环境,specificallypython -m venv venv,然后pip安装。数据库我用的MySQL 8.0,虽然SQLite省事,但毕设文档里写“使用MySQL存储业务数据”更有说服力,而且后期部署到服务器和面试时都是加分项。

用django-admin startproject tea_backend建工程,再python manage.py startapp products和startapp statistics两个App。products管商品和品牌模型,statistics管聚合统计和预测接口。这种按业务域的App划分比一个大App包所有模型要合理得多,将来扩展也容易。

前端用Vite创建Vue 3工程:npm create vite@latest tea_frontend -- --template vue。装依赖用npm install。加Element Plus、Echarts、Axios、Vue Router、Pinia。

这里有个小提醒:Vite的代理配置。开发时前端跑在5173端口,Django跑在8000端口,跨域是必然的。你当然可以在Django里配django-cors-headers,但更好的办法是在vite.config.js里配代理,把所有/api开头的请求转发到8000端口,这样浏览器看到的是同源请求,Cookie和Token都好处理。

// vite.config.js export default defineConfig({ plugins: [vue()], server: { port: 5173, proxy: { '/api': { target: 'http://localhost:8000', changeOrigin: true } } } })

Django这边,Readme上建议用rest_framework.authtoken,在settings里注册,然后登录接口返回token,前端存到localStorage。请求拦截器里加Authorization: Token xxx头,很简洁。

# settings.py INSTALLED_APPS = [ ... 'rest_framework', 'rest_framework.authtoken', ]

3.2 后端核心接口:写一个能打的数据统计接口

以“品牌销售占比”接口为例,完整展示层次。首先定义Serializer:

class BrandStatSerializer(serializers.ModelSerializer): class Meta: model = BrandStat fields = ['brand_name', 'total_sales', 'avg_price', 'product_count']

ViewSet里只做一个简单的list:

class BrandStatViewSet(viewsets.ReadOnlyModelViewSet): queryset = BrandStat.objects.all().order_by('-total_sales')[:50] serializer_class = BrandStatSerializer

然后是路由:

router.register('statistics/brand_share', BrandStatViewSet)

这一套下来前端直接GET /api/statistics/brand_share/就能拿到top50品牌数据,看起来很简单对吧?难点在预计算逻辑,也就是前面说的定时任务。我写了个update_statistics.py的管理命令,用Pandas把所有商品数据读出来,groupby品牌算总量和均价,再写入BrandStat表。调度用APScheduler,在Django的AppConfig.ready()里启动,每天凌晨3点执行一次。这样核心逻辑就是“预计算+常规CRUD接口”,代码量不大,但架构完整性很高。

销量预测接口是另一个重点,后面单独说。

3.3 数据可视化实现:关键图表配置与交互设计

图表做得好不好看,直接影响答辩评委的第一印象。Echarts默认样式其实偏丑,必须认真调。我的经验是,不必每个图都换主题,全局统一一套色彩方案就足够了。在utils/chartTheme.js里定义颜色数组,各图表引用同一组颜色,这样品牌饼图和价格柱状图视觉上就很统一。

核心图表使用方式:

  • 价格分布柱状图:按区间统计商品数量,y轴用对数刻度,因为低价格商品数量通常远大于高价格区间,线性刻度会让高区间柱子几乎不可见。yAxis: { type: 'log' }就能解决。
  • 销量趋势折线图:日期x轴,实际销量和预测销量双线,预测部分用虚线区分,风格上用smooth: true让曲线顺滑。
  • 品牌占比环形图:使用radius: ['35%', '70%']做出环形效果,中心放总销售额文本,通过graphic组件添加。
  • 评论词云:这要和Python的wordcloud工具配合,后端生成词云图片,前端img标签加载。这块可以让图表形式更多样。

还有一个很重要的交互设计:全局筛选器。页面顶部放一个品类选择器(绿茶、红茶、乌龙茶、普洱茶等),所有图表watch这个选项变化后联动刷新。实现方式有两种:一种是把筛选器放在总览页,另一种是定义全局Store(Pinia)保存当前选中品类,所有图表组件统一订阅。我用的是后者,这样即使切到品牌分析页,筛选条件还保持。

3.4 深度学习算法落地:LSTM销量预测

最容易被卡住的部分来了。在项目里加LSTM,前提是必须有一个“历史销量序列”数据。我们这有两万条商品数据是截面数据,做时序预测得有按时间记录的数据。解决这个问题的思路:你爬到的商品评论数可以按月反推一部分历史热度,另外可以依据商品上架时间模拟每天的销量分布,尽量贴近真实曲线。

我构造的数据集是每个品类过去365天的日销量序列。生成逻辑:以当前真实评论数为锚点,用随机游走加周期性波动生成每天的销量。这样预测的目标就是未来7天的销量。训练集和测试集按时间切分,前300天训练、后65天验证。

模型结构:两层LSTM + 一层Dense。输入是过去30天的销量窗口,输出未来7天的销量向量。归一化用MinMaxScaler,窗口滑动取样本。训练就50个epoch,batch_size=32,MSE做损失函数。这个量级在CPU上几分钟就能训完。

model = Sequential([ LSTM(64, return_sequences=True, input_shape=(30, 1)), LSTM(32), Dense(7) ]) model.compile(optimizer='adam', loss='mse')

模型训练好之后存在项目里的../model/sales_lstm.h5,Django接口通过load_model加载,输入最近30天销量数组,predict后把归一化结果还原成真实销量值返回前端。关键代码:

def predict_sales(category_name): scaler_path = f'../model/scaler_{category_name}.pkl' model_path = f'../model/lstm_{category_name}.h5' scaler = joblib.load(scaler_path) model = load_model(model_path) recent_data = get_recent_30_days(category_name) # 返回归一化后的数组 pred_norm = model.predict(recent_data.reshape(1, 30, 1)) pred = scaler.inverse_transform(pred_norm.reshape(-1, 1)).flatten() return pred.tolist()

这里有个容易踩的暗坑:训练和推理时的归一化状态一定要一致。训练时用历史全量的MinMaxScaler拟合,推理时加载同一份scaler文件,不能每次重新fit,否则预测值和真实值量纲就对不上。这个看似小的细节真的是很多人跑通前反复报错或预测结果离谱的原因。

预测结果的前端展示:折线图上画两个区域,历史部分实线,预测部分虚线,中间用一条竖直的参考线隔开。Echarts的markLine可以实现,而且给图形加了“算法感”和“工程感”。

4. 常见问题与排查技巧实录

4.1 前后端联调中的经典故障

第一个高频问题:跨域请求被拦。现象是前端Console里报Access-Control-Allow-Origin错误。虽然前面建议用Vite代理解决,但如果你忘了配,也可以在Django端装django-cors-headers救急。要注意的是both都配好有时反而出问题,因为代理已经转成同源了,后端再返回CORS响应头也没关系,不会冲突。

第二个高频问题:时间字段时区不一致。Django settings里USE_TZ=True时,存储的是UTC时间,前端new Date()之后显示的可能是差8小时的日期。图表上的时间轴看起来“歪了一天”非常迷惑。解决办法是settings里设TIME_ZONE = 'Asia/Shanghai',同时USE_TZ = False,简单直接。毕设系统不需要多时区支持,别给自己添堵。

第三个问题:大数据量下图表卡顿。两个解决思路:后端聚合(传少数据)和前端降采样。比如日趋势数据一年365个点,其实完全不需要每次传今年全年,可以加一个参数控制只取最近90天。如果非要全量,可以考虑用Echarts的sampling: 'lttb',让Echarts自动抽稀,曲线视觉差别不大。

4.2 深度学习的工程化陷阱

除了前面说的归一化一致性,还有几个值得提醒的地方。

模型文件管理。h5文件五十多MB,不能放Git仓库里,否则每次推送都痛苦。用Git LFS,或者在项目里建一个model/目录、加入.gitignore,并写一个README说明训练脚本怎么跑。答辩时你只需要展示推理接口的调用,但代码完整性和可复现性比一个黑盒模型更重要。

数据泄漏。这是真正能“一票否决”模型质量的问题。如果我用含测试期的数据去训练,预测的测试结果自然好看,但答辩老师一眼看出来就不太好了。时序数据的标准操作是:切分时按时间点切,训练集只包含测试集之前的数据;归一化时scaler先在训练集上fit,然后再transform测试集,不能让测试集参与scaler的fit过程。

4.3 部署与演示环节避坑

毕设至少要能演示,最稳的是本地演示,但部署到云服务器上会让项目显得更“真”。服务器选2核4G的轻量就够,Ubuntu 22.04。部署方案:后端用Gunicorn跑,前端npm build出静态文件后用Nginx托管。

Nginx配置很简单:location / { root /var/www/tea_frontend/dist; try_files $uri $uri/ /index.html; },location /api/ { proxy_pass http://127.0.0.1:8000; }。注意Spa路由的try_files一定要写,否则刷新页面会404。

部署之前建议在本地先跑一遍生产构建。Vue的npm run build如果报错,很可能是环境变量没配。像VITE_API_BASE_URL这种,生产时走same origin所以留空就行,让Nginx代理解决。

另外数据库迁移务必提前执行:

python manage.py collectstatic --noinput python manage.py migrate

服务器的MySQL字符集要明确设成utf8mb4,不然商品名里的特殊字符可能报错Incorrect string value。我在第一次部署时就被这个坑过,改了/etc/mysql/mysql.conf.d/mysqld.cnf里character-set-server = utf8mb4重启就好了。

4.4 答辩准备与项目亮点提炼

代码跑通只是第一步,答辩的呈现方式同样重要。老师大概率会问这样几个问题:

  • “数据量多大?为什么叫大数据系统?”——回答时要强调数据采集规模(两万余条商品、百万级评论)、数据分层架构、预计算策略,说明这是一个面向一定数据规模设计的系统。
  • “为什么选LSTM?有没有比较过其它模型?”——说清楚LSTM适合序列数据、能捕获长期依赖,同时坦率地说也实验了ARIMA作为基线,LSTM在预测误差指标上更优。这个对比实验你最好真做,运行一次ARIMA用不了多少时间,但答辩效果完全不一样。
  • “如果数据量翻100倍,系统哪里会成为瓶颈?怎么解决?”——这是送命题也是送分题。你只要说出“ORM聚合压力大,可以引入ClickHouse或者把离线统计任务迁移到Spark;同步接口改异步消息队列”,老师就知道你真的考虑过扩展性。

我个人经验是,整个项目最花时间的其实不是写核心代码——爬虫、清洗、模型调参、前端样式和部署,几乎每一个环节都有这样那样的细节问题。真正让项目“有灵魂”的,是打通了从数据采集到算法预测再到可视化展示的完整链路,而不是某一个花哨功能。

最后分享一个小技巧:在所有统计接口的返回里加上update_time字段,让前端页面显示“数据更新于x分钟前”。一方面提示评委数据是动态更新的定时任务成果,另一方面也让系统看起来更像一个真正的在线分析平台。这种小细节,往往是项目和Demo之间最大的区别。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/30 3:53:03

小程序商城里商品放多少合适:SKU 多了反而下单更少

小程序商城里商品放多少合适:SKU 多了反而下单更少不少公司上小程序商城的第一件事是把全部商品都放上去:一万多个 SKU,看着很齐全。上线一个月的数据往往很难看:访问不少,下单很少。原因不在流量,在“选择…

作者头像 李华
网站建设 2026/9/30 3:53:02

AI Engineering从零构建:生产级模型服务系统设计

1. 这不是“搭积木”,而是亲手锻造AI系统的底层逻辑“AI Engineering from Scratch”——这个标题乍看像一句技术宣言,实则是一道分水岭。它不指代用现成框架微调一个模型,也不等于在Colab里跑通一段Hugging Face示例代码。它意味着&#xff…

作者头像 李华
网站建设 2026/9/30 3:52:34

ZenFlow AI:免登录本地优先的Todo+番茄钟+生产力分析工具

1. 为什么我做了 ZenFlow AI 这样一个“怪”工具ZenFlow AI 是一款把 Todo、番茄钟、生产力分析三种能力塞进同一界面的小工具,主打三个关键词:无广告、免登录、自由度高。当初我想做它,不是觉得市面上的效率软件不够多,恰恰相反&…

作者头像 李华
网站建设 2026/9/30 3:51:45

AI工程化从零构建:生产级推理系统实战指南

1. 这不是“搭积木”,而是亲手锻造AI系统的底层逻辑“ai-engineering-from-scratch”这个标题,乍看像一句技术口号,但在我带过二十多个工业级AI项目、亲手从零部署过七套生产环境推理服务之后,我越来越确信:它根本不是…

作者头像 李华
网站建设 2026/9/30 3:50:37

SQL Server常用函数实战清单:日期、字符串与聚合统计详解

聊到SQL Server,绝大多数人最先想搞明白的就是日期转换、字符串处理、数学计算和聚合统计这四类常用函数。我做了这么多年数据相关的工作,凡是写报表、做数据分析、维护数据库后台,翻来覆去用的也就是这些功能。这篇就把SQL Server里最常用的…

作者头像 李华