
1. 项目核心思路与整体拆解做毕业设计最怕什么不是不会写代码而是选了个满大街都是的题目开题报告写得费劲答辩时老师一眼看穿没有技术含量。“DjangoVue.js租房推荐系统”这类题目表面看是拼装了一个前后端分离的Web应用但仔细拆解它把推荐算法、数据可视化、大数据分析三个高价值标签全占了而且每个模块都能独立展开深挖这正是答辩时最能加分的地方。1.1 核心需求解析毕设选题为什么是它租房信息平台本身并不新鲜市面上贝壳、自如、链家早就做透了。但如果把视角从“一个租房网站”切换到“一个完整的推荐系统”思路就完全不一样了。这个题目的第一层价值在于它天然具备“用户-房源”双端数据。用户有点击、收藏、预约看房行为房源有户型、租金、位置、配套设施属性。基于这些数据我们可以做基于协同过滤的个性化推荐也可以做基于内容的属性匹配推荐甚至可以把两者做成混合推荐来提升精度。这些内容往论文里一放“基于用户行为的个性化租房推荐研究”这个研究方向比单纯写个增删改查的毕设有说服力得多。第二层价值在于“大屏可视化”这个点。大数据这个标签在毕业设计里含金量很高但很多同学不知道落地到什么地方。“租房大屏可视化”是一个非常好的载体把房源价格分布、区域热度、户型需求比、租金走势用大屏形式呈现出来既有视觉冲击力又有数据价值。而且现在很多高校的毕设要求里都有“数据可视化”这个指标大屏是最容易出效果的部分。第三层价值在于技术栈覆盖率。Django负责后端、ORM模型、JWT认证、接口开发Vue.js负责前端SPA页面、组件化开发、状态管理、ECharts图表交互Redis做热门房源的缓存和点击行为队列MySQL做业务数据持久化推荐算法模块可以用协同过滤也可以用简单规则。这一套组合拳打下来技术栈的广度是够的每个点都能在论文里单独开一个章节去写。1.2 系统架构与核心功能地图整个系统从前到后可以拆成四层数据层MySQL存储用户信息、房源信息、收藏记录、浏览历史Redis缓存热门房源和用户实时行为。后端服务层Django Django REST Framework提供RESTful API包含用户模块、房源模块、推荐模块、统计模块推荐模块基于用户的协同过滤算法实时计算相似用户和推荐列表。前端应用层Vue.js单页应用页面分为C端用户端浏览、搜索、收藏、推荐和可视化大屏端数据总览、价格走势、区域热度、户型分布。部署运维层开发环境用前后端分离模式后端跑Django自带的开发服务器前端用Vite或WebpackDevServer代理生产环境Nginx托管前端静态文件并反向代理后端的API请求。具体到功能模块我建议至少覆盖这几个核心闭环用户注册和登录是必须有的房源浏览与条件筛选区域、户型、租金范围、朝向是基础收藏和取消收藏用于积累用户行为数据基于收藏和浏览记录生成推荐列表是核心卖点管理后台做房源的增删改查大屏可视化作为独立页面展示统计数据。这里要说一个我在初期踩过的坑千万不要把“推荐系统”只做成一个摆设按钮。很多同学的毕设推荐列表是后端随机出的假数据虽然答辩时能混过去但经不起追问。建议至少让协同过滤算法真正跑起来哪怕数据量不大逻辑完整了老师问起来你也能挺直腰杆。2. 环境准备与项目初始化这套系统虽然技术栈多但环境搭建并不复杂。我建议开发环境统一用Python 3.10以上版本和Node.js 16以上版本尽量别用太老的版本——新版本不是追求新鲜主要是Django 4.x和Vue 3都已经非常稳定并且相关的第三方库兼容性也做得更好了。2.1 后端Django项目搭建新建一个独立的虚拟环境是必须的第一步前后端依赖放一起后面一定会出问题。我习惯用venv命令也简单mkdir rental_recommend cd rental_recommend python -m venv venv # Windows激活 venv\Scripts\activate # macOS/Linux激活 source venv/bin/activate激活虚拟环境后安装核心依赖。Django版本我推荐4.2 LTS版配合Django REST Framework做接口开发django-cors-headers解决跨域djangorestframework-simplejwt做基于JWT的登录认证Redis连接统一用django-redis。pip install django4.2.* pip install djangorestframework pip install django-cors-headers pip install djangorestframework-simplejwt pip install django-redis pip install pandas numpy创建Django项目和应用。项目名我习惯叫rental_backend应用按模块拆users管理用户houses管理房源recs做推荐stats做统计连管理后台都省得重新写。django-admin startproject rental_backend cd rental_backend python manage.py startapp users python manage.py startapp houses python manage.py startapp recs python manage.py startapp stats在settings.py中把应用注册进去再配置好数据库连接。MySQL比SQLite好在能扛更大的数据量毕业后你如果还想往简历上放MySQL经验也算加分项。DATABASES { default: { ENGINE: django.db.backends.mysql, NAME: rental_db, USER: root, PASSWORD: 你的密码, HOST: 127.0.0.1, PORT: 3306, OPTIONS: {charset: utf8mb4}, } }再在settings.py里把REST_FRAMEWORK和SIMPLE_JWT的配置补上身份认证用JWT权限默认为AllowAny之后在需要登录的接口上单独加IsAuthenticated权限类。跨域这块把CORS_ALLOW_ALL_ORIGINS设为True在开发阶段最省事部署到生产环境再收紧。2.2 前端Vue.js项目搭建前端我用Vite搭建Vue 3项目相比Vue CLIVite启动速度明显更快开发体验也更好现在绝大多数教程和团队都切过来了用旧版反而容易踩坑。npm create vitelatest rental_front -- --template vue cd rental_front npm install npm install vue-router4 axios element-plus echarts这里顺便解释一下为什么选Element Plus而不是别的UI库。租房系统涉及大量的列表、表单、标签、轮播图Element Plus组件全覆盖后端管理页面可以直接用el-table、el-form、el-dialog快速搭出来对毕设开发效率提升非常明显。ECharts则是做大屏可视化的事实标准地图、折线图、饼图都支持得非常好。启动开发服务器后Vite默认跑在5173端口Django跑在8000端口跨域就产生了。前面在Django里配置django-cors-headers就是为了让浏览器允许这两个端口之间互相通信。开发阶段我还习惯在vite.config.js里配一个代理把/api开头的请求转发到后端这样前端代码里就用相对路径请求部署到服务器上不用改代码。server: { port: 5173, proxy: { /api: { target: http://127.0.0.1:8000, changeOrigin: true } } }2.3 数据模型设计从业务出发的表结构数据模型是后端的灵魂表结构设计好了后面写接口和推荐算法都会顺畅很多。我们至少需要四张核心表用户表、房源表、收藏记录表、浏览记录表。用户表可以直接用Django自带的User模型扩展添加一个手机号字段、头像字段和用户类型字段。房源表字段比较多包括标题、描述、户型几室几厅、面积、朝向、楼层、租金、押金、所在区域、详细地址、经纬度坐标、配套设施用JSON格式存储比如地铁、电梯、阳台、房屋图片存多个URL、是否已出租、发布时间等。收藏记录表关联用户和房源外加一个收藏时间。浏览记录表关联用户和房源记录浏览时间。这样设计之后推荐算法所需的数据源就齐了。用户的行为数据浏览、收藏是协同过滤的输入房源属性数据是内容推荐的基础。统计模块则可以直接用Django ORM做聚合查询比如统计每个区域的房源数量、平均租金、户型占比等。3. 推荐模块的核心实现推荐系统是这个毕设真正的灵魂也是最容易在答辩时被追问的模块。我采用的方案是经典的基于用户的协同过滤再加上一个基于内容的冷启动策略做兜底这样既保证算法可解释又不会因为数据稀疏导致推荐列表为空。3.1 协同过滤算法原理与实现步骤基于用户的协同过滤核心思想是如果用户A和用户B在过去的收藏/浏览行为上高度相似那么A喜欢的房源B大概率也会喜欢。算法分三步骤第一步构建用户-房源行为矩阵。行是用户列是房源值可以是是否收藏0/1也可以是浏览次数的加权分数。我建议简单一点收藏记1分浏览记0.5分这样不同行为可以加权累加。第二步计算用户之间的相似度。可以通过余弦相似度两个用户的向量点积除以两个向量模长的乘积。Django里用Python就能实现不需要额外依赖。但要注意当用户量比较大上万级别时需要转换成矩阵运算这时numpy或者pandas会更高效。第三步为目标用户推荐。找出与当前用户最相似的K个邻居把这K个邻居收藏过但当前用户没收藏过的房源汇总按相似度加权后的分数从高到低排序取前N条作为推荐结果。这里给一个简化的实现示例基于pandasimport pandas as pd import numpy as np def build_user_item_matrix(records): df pd.DataFrame(records, columns[user_id, house_id, score]) matrix df.pivot_table(indexuser_id, columnshouse_id, valuesscore, fill_value0) return matrix def cosine_similarity(matrix): norm np.linalg.norm(matrix, axis1, keepdimsTrue) matrix_norm matrix / np.where(norm 0, 1, norm) return np.dot(matrix_norm, matrix_norm.T) def recommend_for_user(user_id, matrix, sim_matrix, k5, top_n10): user_idx list(matrix.index).index(user_id) sim_scores sim_matrix[user_idx] similar_users np.argsort(sim_scores)[::-1][1:k1] # 聚合邻居收藏过的房源排除当前用户已收藏的 ... return top_house_ids3.2 冷启动问题与内容推荐兜底方案协同过滤有个典型问题新用户没有行为数据算什么相似度新房源没有用户收藏过怎么被推荐这就是冷启动。针对用户冷启动我用基于内容的推荐做兜底。新用户注册后可以补充一个偏好问卷可跳过选择意向区域、预算区间、偏好户型。推荐模块直接按这些偏好筛选房源返回前N条。如果用户连问卷都跳过了那就按热度推荐也就是按浏览量、收藏量加权排序或者按最新发布排序。针对房源冷启动关键是不要让它永远沉没。我是这样处理的在推荐结果里加入“新鲜度”因子在其它得分相同的条件下最近发布的房源排前面。同时后台管理可以在推荐模块里配置一个“人工置顶”功能把新录入手动的房源推到推荐流保证它有曝光机会。这里要强调一个经验无论你用什么算法推荐列表在返回给前端时一定要记录下这次推荐的结果和当时的用户行为数据。3.3 行为数据采集与异步化处理光有算法不够还要让数据源源不断地流进来。我可以直接在视图层埋点用户浏览房源详情时前端调用一个记录浏览记录的接口用户点击收藏时调用收藏接口同时把行为ID写入Redis的队列里。后端异步任务再从Redis队列取数据写入MySQL。为什么绕一圈用Redis而不是直接写MySQL因为浏览行为是高频操作如果每个请求都去数据库执行INSERT高并发下数据库压力大而且也会拖慢接口响应。用Redis做消息缓冲先快速写入内存再异步批量落库这是生产环境的标准做法。Node里可以用celery这类异步任务队列但毕设里我尽量简化——直接用Django的channels或一个简单的threading定时任务也能做只要把落库刷盘逻辑写清楚就行。还有一个细节用户的行为数据表不需要保存太久。在真实场景里三个月以前的行为对推荐的意义不大而且表越来越大影响查询性能。我们在毕业设计中也可以通过定时任务定期清理三个月以上的浏览记录这样既控制了数据规模也符合实际情况。4. 可视化大屏的设计与实现大屏可视化是给评委第一印象加分的关键模块。一张布局工整、配色统一的大屏让系统“大数据”的标签瞬间立住了。4.1 大屏数据接口与统计设计大屏不能是静态假数据必须从后端统计接口实时拉取。我建议至少准备四个核心统计接口总览指标总房源数、总用户数、今日新增房源、今日新增用户、整体出租率。区域热度分析按区域分组统计房源数量、平均租金、出租率返回列表供地图或柱状图展示。租金走势按月份统计租金中位数和平均值观察价格变化趋势。户型分布按户型一室/两室/三室/四室及以上统计房源数量占比。后端用Django ORM就能完成聚合查询from django.db.models import Count, Avg from houses.models import House def region_stats(request): data ( House.objects .values(district) .annotate(countCount(id), avg_priceAvg(rent_price)) .order_by(-count) ) return JsonResponse(list(data), safeFalse)为了让大屏看起来更“实时”可以在前端设置定时轮询比如每30秒请求一次接口更新图表数据如果后续有条件可以改造为WebSocket推送。但毕设用轮询完全够用而且代码好写不引入额外复杂度。4.2 ECharts核心图表配置与实时刷新大屏页面我用的是深色科技风。背景是深蓝色渐变辅以霓虹色系青色、橙色作为图表主题色。具体实现上ECharts支持自定义主题可以把颜色配置提取成公共对象统一管理。以区域房源地图为例大屏中央放一个全国地图或城市地图区域上用不同颜色的散点表示房源密度点击某个区域还能下钻展示该区域的细部信息。ECharts官方提供了地图注册方法只要准备好GeoJSON数据就能快速集成import * as echarts from echarts import geoJson from /assets/china.json echarts.registerMap(china, geoJson) const chart echarts.init(document.getElementById(map)) chart.setOption({ series: [{ type: map, map: china, roam: true, label: { show: false }, itemStyle: { areaColor: #1a2b4a, borderColor: #3a6ea5 }, emphasis: { label: { show: true }, itemStyle: { areaColor: #2f89cf } } }] })底部放租金趋势折线图和户型占比饼图用ECharts的Grid布局排列。轮询刷新我这里直接封装成一个工具方法function startPolling(url, callback, interval 30000) { const fetchData async () { const res await axios.get(url) callback(res.data) } fetchData() const timer setInterval(fetchData, interval) return () clearInterval(timer) }4.3 大屏适配与前端工程化做可视化大屏一个容易被忽略但极其影响观感的细节是屏幕分辨率适配。不同分辨率的屏幕下1920×1080、2560×1440、甚至4K图表大小必须自适应。我用一套非常成熟的做法按1920×1080设计稿开发外层容器设置固定宽高然后通过transform: scale()做整体缩放。大致逻辑是function screenAdapter() { const designWidth 1920 const designHeight 1080 const scaleX window.innerWidth / designWidth const scaleY window.innerHeight / designHeight const scale Math.min(scaleX, scaleY) document.getElementById(screen).style.transform scale(${scale}) } window.addEventListener(resize, screenAdapter)为什么用缩放而不是百分比布局因为固定设计稿能够保证图表内字体、间距在视觉上绝对统一不会因为屏幕比例不同导致布局错乱。这是大屏项目的通用做法实测在投影和显示器上都表现良好。4.4 大屏页面与后端接口的联调优化前后端联调时最容易出现的问题是大屏页面在加载时多个图表并发请求后端导致后端压力过大或者响应变慢。我的优化方案是两板斧第一板斧后端接口做Redis缓存。像区域统计、租金走势这类数据变动频率并不高完全可以缓存5分钟减少数据库压力from django.core.cache import cache def region_stats(request): data cache.get(region_stats) if data is None: data list(House.objects.values(district).annotate(...)) cache.set(region_stats, data, timeout300) return JsonResponse(data, safeFalse)第二板斧前端控制请求时序。首屏先请求最核心的总览指标和区域数据等这两个渲染出来了再去请求租金走势和户型占比。避免4个图表同时发请求给用户一种瞬间加载完成的感觉。5. 常见问题与排查技巧实录在开发这个项目的过程中我从环境配置到部署上线踩了不止一个坑这里整理几个最常见的问题和排查方法希望能帮大家少走弯路。5.1 跨域请求失败接口502/403前端开发服务器在5173端口后端在8000端口浏览器默认阻止跨域请求。解决方式我在第二章节提到了配置CORS中间件但还有两个细节需要注意第一django-cors-headers必须放在MIDDLEWARE列表尽量靠上的位置最好在CommonMiddleware之前否则可能部分请求不生效第二如果你用了JWT认证前端请求时必须在Authorization头里带上Bearer token否则接口返回401非常容易误判为跨域问题。5.2 图片上传/显示404静态文件丢失租房房源图片很多前端有时显示404。这个问题多半出在Django的静态文件处理和MEDIA路径配置上。在settings.py里要保证MEDIA_URL /media/ MEDIA_ROOT BASE_DIR / media然后在主工程urls.py里配好from django.conf import settings from django.conf.urls.static import static urlpatterns static(settings.MEDIA_URL, document_rootsettings.MEDIA_ROOT)开发环境这样配就没问题了。生产部署用Nginx托管/media路径指向本地的media目录。5.3 推荐接口响应慢从1秒优化到200毫秒以内我的推荐接口起初很慢排查发现每次请求都重新计算了一遍协同过滤矩阵——在数据量小的时候还行数据量稍大就延迟明显。优化思路是把用户相似度矩阵缓存到Redis每20分钟更新一次行为数据变化后重算。当前用户的推荐列表也缓存10分钟。把向量计算用numpy重写代替纯Python循环。这一套下来接口耗时从900毫秒降到了200毫秒以内效果立竿见影。毕设在答辩演示时流畅的响应速度也是一个隐形的加分项。5.4 Redis未启动导致登录接口直接白屏很多同学会在本地开发时忘记启动Redis服务结果前端点击登录后后端直接抛异常或者卡住。排查思路很简单首先在浏览器DevTools里看Network标签确认请求是否发出再看后端的命令行输出有Exception说明后端崩了如果是Redis连接超时的报错启动Redis服务即可——Windows下可以用redis-server启动本机服务macOS/Linux则用redis-server或sudo systemctl start redis。5.5 前端页面样式异常Vue组件加载不出来如果Vue页面加载后一片空白大概率是组件导入路径写错或者是Vue Router配置有问题。先在控制台看有没有大量404的JS请求再检查路由的history模式是否需要服务器支持。开发环境用createWebHashHistory()最省心部署到Nginx再用createWebHistory()并配置好try_files回退。另外大屏页面的transform: scale()容器有时会跑出视口记得给最外层加overflow: hidden。6. 部署上线与毕设答辩加分项毕业设计写代码是基础把它包装好、讲清楚才是拿高分的关键。部署方案我推荐Nginx uWSGI或Waitress在服务器上跑但毕设如果只需要本地演示也可以简化成前后端分离但都跑在一台机器上的方案。6.1 生产环境部署方案与步骤第一步前端构建。在rental_front目录下执行npm run build生成dist目录。Nginx的根目录指向dist同时配置location /api反向代理到Django后端接口。第二步后端部署。我自己的经验是如果服务器是Windows可以直接用waitress代替uWSGIWindows中央管理的支持不友好pip install waitress waitress-serve --port8000 rental_backend.wsgi:application如果是Linux服务器uWSGI或Gunicorn二选一。启动命令和配置方式网上很多我这里不再赘述但要强调Gunicorn的进程数不要贪多一般CPU核心数加1就够了。第三步数据库配置好MySQL初始化好数据表然后创建管理员账户。在settings.py里把DEBUG设为False配置好ALLOWED_HOSTS把后端的SECRET_KEY换成新的随机值。6.2 答辩演示准备工作如何让系统在5分钟内讲清楚答辩演示是整个毕设的临门一脚。我的建议是事前准备好以下几条演示路径从用户注册登录讲起展示前后端分离的架构说清楚JWT认证流程。演示用户浏览房源、收藏房源尽量多制造一些“行为数据”。展示推荐列表切换几个不同偏好的用户让推荐结果有明显差异。打开大屏可视化页面讲解统计数据是怎么来的每个图表对应后端哪个接口。有准备地讲讲冷启动、缓存优化和异步落库这三个点马上能拉开与普通毕设的差距。把系统的亮点放到前面讲让老师迅速感受到工作量和技术含量后面的提问环节你也能游刃有余。6.3 经验心得这套架构还能往哪儿扩展系统做完后我把它扩展成了一个小型的数据分析平台把用户行为数据导出成CSV用pandas做基础分析再用上次讲的K-means聚类把用户按照租房偏好分成几类人群然后基于人群特征做差异化推荐。这样一下子就把“大数据”这个词落到了实处而不是停留在口号上。如果你时间充裕也可以把Spark接进来做离线的推荐计算或者把前端改成小程序版本。但说实话对于本科毕业设计来说DjangoVue.js协同过滤可视化大屏这套组合已经足够扎实了把现有模块做精做深远比再铺一个新功能更划算。我自己带过好几个师弟师妹做类似的选题最大的共性问题不是技术不会而是文档和代码对不上。所以我的最后一个建议每完成一个模块立刻截图、记录笔记并同步更新开题报告和论文——等到最后集中写文档那你一定会后悔。这个项目做下来代码量不算大但逻辑链条很长靠临时记忆很难完整复盘。养成边写代码边沉淀文档的习惯你会发现后面的毕业论文写得异常顺溜。