1. 项目定位与整体方案拆解1.1 毕业设计选题怎么看每年毕业季都有大量同学选择XX推荐系统这类题目租房推荐系统在其中算是非常经典也比较好落地的一个方向。原因很简单推荐系统类题目天然自带算法亮点又不缺业务场景答辩时有东西可讲文档也容易写得丰满。相比纯CRUD的租房管理系统加上了推荐和大屏可视化这两个词之后整个项目的技术含量和展示效果都上了一个台阶拿高分或者评优的概率明显更大。借这个标题说句实话计算机毕业设计能不能做出来是一回事能不能讲清楚是另一回事。我接触过不少做这类题目的同学技术本身不复杂但很多人在选题之初就栽了跟头目标定得太散功能堆得多但彼此不关联最后系统做出来像个功能集合而不是一个产品。所以拿到这个题目第一件事情不是写代码而是把系统的核心逻辑先定下来。这个租房推荐系统本质上是三层结构数据层房源信息、用户行为收藏、浏览、租住、租金走势等数据的存储与访问。业务层用户注册登录、房源检索筛选、推荐算法计算、订单预约等核心业务逻辑。展示层PC端房源浏览与管理后台、推荐结果展示、租房数据大屏可视化三个端各司其职。选这个题目的同学真正需要向评委证明的点不是你会不会写增删改查而是你有没有能力把推荐算法跑起来、把数据可视化做得直观、把前后端分离架构组织得清晰。只要这三个点站得住项目就成功了一大半。1.2 为什么是DjangoVue.js前后端分离技术选型不能只看哪个火选哪个要看你做的是毕业设计需要在论文里把理由讲得通。DjangoVue.js是目前前后端分离毕业设计最常见的组合这个选型本身就非常经得起追问。Django作为后端框架的优势在于一条龙服务。ORM、Admin后台、认证系统、路由分发这些全都是现成的写一个推荐系统原型非常快。特别是Django自带的Admin在做毕业设计阶段可以节省大量管理后台的搭建时间你完全可以把精力集中在推荐算法和可视化前面端上。对大部分只学过一个学期Python课程、没深入接触过后端框架的同学来说Django的文档和社区资源也是最友好的。Vue.js的优势则在于组件化开发的思路。整个租房前端界面可以拆成房源卡片、搜索栏、筛选面板、推荐列表、数据大屏等独立组件一个人开发时思路会非常清晰。更重要的是Vue的响应式数据绑定让你在做筛选功能时几乎不用手动操作DOM用户体验层面的开发效率至少翻一倍。前后端分离还有一个隐性好处答辩的时候你可以明确说系统的前后端通过RESTful API通信耦合度低便于后期各自独立扩展。这句话在论文的系统架构章节里是很值钱的。提示选型时不要被推荐系统是不是该用微服务大数据是不是得上Hadoop这类问题带偏。本科毕业设计强调的是一个完整、自洽的工程闭环Django提供完整后端能力Vue.js提供灵活前端呈现两者组合已经足够覆盖前后端分离数据可视化的全部要求。1.3 推荐算法选型别一上来就搞深度学习标题里有推荐系统但绝大多数选题学生的误区是把推荐算法想得太高大上觉得一定要用深度学习才显得有水平。实际上在租房这个场景下深度学习的效果未必比经典算法好而且答辩时很难说清楚训练过程和参数调整逻辑。我的建议是主推基于物品的协同过滤Item-based Collaborative Filtering或基于内容的推荐用其中一个作为核心卖点另一个作为补充策略这个组合既解释了冷启动问题也让论文的算法设计章节有足够的展开空间。推荐理由有三个。第一租房数据天然适合基于内容的推荐每套房源有户型、面积、价格、位置、朝向、配套等结构化属性计算相似度非常方便甚至不需要像电商系统那样清洗大量的文本描述。第二协同过滤的效果依赖于用户行为数据而毕业设计里很难拿到真实大规模用户行为数据模拟数据的生成逻辑需要你自己设计这时候如果算法本身太复杂数据生成的合理性会很难自圆其说。第三评委老师通常很关注算法是否适合业务场景你能够说明白为什么选这个算法而不是那个算法远比把代码塞得满满当当更让人信服。就我自己做过的项目经验来说简单有效的路线是基于物品协同过滤计算看过该房源的人还看过哪些房源基于内容的推荐负责处理新用户冷启动再配合一些简单的热度加权浏览量、收藏量、预约量已经能产生相当惊艳的推荐效果。标题里用了大数据毕业设计这个词你完全可以在文档里解释为基于大量模拟租房数据挖掘用户偏好模式而不是真的要用Spark集群跑数据。2. 系统架构与核心细节设计2.1 数据库建模一切业务的基石做房间推荐系统最容易忽略的是数据库设计。很多人上来就建一张房源表、一张用户表、一张收藏表然后不假思索地开始写接口结果做到推荐模块和可视化模块时发现缺少数据支撑被迫回头改表结构。数据库设计如果前期不规划到位后期返工的代价远超过你的想象。针对租房业务我建议至少设计以下核心数据表表名核心字段用途说明tb_userid, 用户名, 密码(Hash), 手机号, 注册时间用户登录与推荐记忆tb_houseid, 标题, 小区, 户型, 面积, 价格, 地址, 经纬度, 标签, 图片房源基础信息tb_house_clickid, 用户id, 房源id, 点击时间, 点击次数用户行为数据tb_user_favoriteid, 用户id, 房源id, 收藏时间用户显式偏好数据tb_orderid, 用户id, 房源id, 预约时间, 状态订单/预约业务tb_house_commentid, 用户id, 房源id, 评分, 内容, 时间用户反馈与评分数据这里有一个容易被忽视的细节行为数据表最好带点击次数和停留时长字段。因为推荐算法的输入不仅依赖收藏这种显式行为更需要浏览记录这种隐式反馈。没有行为数据协同过滤就成了无源之水。可视化大屏模块还需要考虑数据统计的来源。推荐的做法不是在大屏组件里临时用ORM查一堆表再聚合而是设计一个tb_statistics表定期或实时把房源总量、租金均值、区域分布、价格区间分布、户型占比等统计结果写进去。大屏界面只管读这张表的汇总数据性能会好很多架构也清晰。注意所有涉及价格和面积的字段类型务必用DECIMAL和量化的整数不要在数据库里存500-800元/月这种字符串否则你在做价格区间筛选和可视化统计时欲哭无泪。这是踩过的坑。2.2 后端项目组织按功能模块拆分工坊Django项目最常见的误区是把所有业务逻辑堆在app里导致一个app几千行代码后期维护非常痛苦。推荐系统这种项目后端我建议按模块拆分成多个app职责分明renting_system/ # 项目根目录 ├── manage.py ├── config/ # 项目的配置目录 │ ├── settings.py │ ├── urls.py │ ├── asgi.py │ └── wsgi.py ├── apps/ │ ├── users/ # 用户认证与个人信息 │ ├── house/ # 房源模型、搜索、筛选、详情 │ ├── recommend/ # 推荐算法核心逻辑 │ ├── order/ # 预约订单业务 │ ├── statistics/ # 统计与大屏数据接口 │ └── common/ # 通用工具函数、统一返回格式把recommend单独抽成一个app是一个比较关键的设计决定。推荐逻辑和普通的CRUD接口不同它有单独的数据预处理、算法调用、结果缓存逻辑如果在house或者users里去实现会让代码耦合度快速上升。统一返回格式也是必须提前做的一件事。前后端分离项目最怕接口乱我建议在common里封装一个统一响应类格式如下{ code: 200, message: success, data: {} }所有接口都走这个统一格式前端Axios拦截器只需处理一个规则不用每写一个接口就调试一次错误处理逻辑。这个看起来是小事但在联调阶段能帮你省下大量时间。2.3 前端Vue项目结构与路由设计Vue前端部分重点在于页面路由设计和组件复用。租房推荐系统的前端一般包含以下几个核心视图首页推荐列表搜索、房源详情、个人中心收藏/预约/浏览记录、管理后台发布房源/管理订单、数据大屏。推荐系统的前端路由可以这样设计/ 首页猜你喜欢推荐 热门房源 搜索栏 /house/:id 房源详情页详情、相似房源推荐、用户评论 /search 条件筛选区域、价格、户型、地铁线 /user 个人中心收藏夹、浏览历史、预约订单 /admin/publish 房源发布与管理 /screen 数据可视化大屏 /login 登录注册这里想把一个细节强调一下大屏页面不要放在常规布局组件里。大屏的展示逻辑和常规页面完全不同它通常是全屏的有自己独立的路由不需要导航栏和底栏甚至不需要用户登录。你可以把ScreenView单独作为顶层路由不走Layout组件渲染这样调试时就直接访问/screen全屏展示好看也好讲。组件层面我会把房源卡片拆成独立组件HouseCard因为它在首页推荐、搜索结果页、相似房源、收藏夹里都会出现同一个组件复用四个场景代码维护成本成倍降低。2.4 DTO与API交互规范前后端分离项目中的沟通介质是JSON接口设计直接决定了前后端开发的并行效率。设计接口时应该尽量遵循RESTful风格但不必过度拘泥。以房源相关的接口为例POST /api/users/register 用户注册 POST /api/users/login 用户登录 GET /api/houses/list 房源分页列表 GET /api/houses/search 条件筛选房源 GET /api/houses/detail/{id} 房源详情 POST /api/favorites/add 收藏房源 DELETE /api/favorites/remove/{id} 取消收藏 GET /api/recommend/cf/{user_id} 协同过滤推荐 GET /api/recommend/content/{user_id} 内容相似房源推荐 GET /api/statistics/overview 大屏总览数据 GET /api/statistics/trend 租金趋势每个接口必须有明确的分页参数。推荐列表的接口返回不应该只返回房源数组还要返回推荐依据的说明比如因为您浏览过XX小区为您推荐相似小区房源。这个细节在答辩和演示时非常加分评委能看到推荐结果不是随机推荐的而是有理由的。实践建议用Postman或Apifox把所有接口整理集合。调试阶段每天都会频繁调用接口没有规范的管理工具你会陷入到底后端改了没有的混乱状态中。3. 推荐算法的详细实现与优化3.1 基于物品的协同过滤基于物品的协同过滤核心思想用户对与历史偏好物品相似的其他物品也会有偏好。用在租房场景里就是这位用户收藏/浏览过A房源A房源和B房源在户型、价格、位置上都很相似那用户大概率也会喜欢B。算法步骤分成三步第一步构建用户-房源行为矩阵。行为分数可以这样定义浏览1分收藏3分预约5分。分数权重是经验值你可以根据项目演示效果调整。行为矩阵就是一张稀疏表行是用户列是房源值是对应的行为分数。第二步计算房源之间的相似度。我推荐使用皮尔逊相关系数或调整后的余弦相似度。余弦相似度公式如下similarity(A, B) Σ(用户对A的评分 × 用户对B的评分) / (sqrt(Σ(用户对A评分²)) × sqrt(Σ(用户对B评分²)))在实际写代码时不要自己造轮子直接用 pandas 和 numpy 实现矩阵运算代码量非常少。比如你可以这样组织数据import pandas as pd import numpy as np # 假设有三个表用户行为表、房源表 # 构建用户-房源评分矩阵行用户id列房源id user_item_matrix pd.pivot_table( behavior_df, indexuser_id, columnshouse_id, valuesscore, fill_value0 ) # 计算房源间的余弦相似度 item_sim_matrix pd.DataFrame( cosine_similarity(user_item_matrix.T), indexuser_item_matrix.columns, columnsuser_item_matrix.columns )第三步为目标用户生成推荐列表。找到用户历史行为里的所有房源获取每个房源最相似的Top-N房源排除用户已经行为过的房源最后按照相似度加权分值排序取Top-K作为推荐结果。过程中潜在问题比较大的步骤是数据稀疏性处理如果用户行为太少协同过滤效果会很差这就是为什么需要基于内容的推荐来打底。建议最开始用正常逻辑模拟一批行为数据比如几千个用户、几千条房源记录每个用户至少有10-20条行为记录这样算法跑出来效果才肉眼可见。3.2 基于内容的推荐冷启动的解法新用户没有行为数据协同过滤无法工作基于内容的推荐恰好能解决这个问题。逻辑是从用户注册时填写的偏好信息比如偏好区域、预算范围、户型出发计算候选房源与偏好条件的匹配度。在逻辑实现上我建议这样打偏好分注册时让用户选择几个标签比如区域、价格范围、户型偏好、是否允许合租、是否近地铁然后从房源标签和属性出发计算匹配分值content_score w1 * 区域匹配 w2 * 价格匹配 w3 * 户型匹配 w4 * 配套匹配权重w可以动态调整。如果后续用户有行为记录了就逐步用协同过滤结果替代内容推荐结果形成先内容后协同的动态策略。放到论文里这叫混合推荐策略是一个很好的论述点。实现层面基于内容的推荐其实就是写一个打分函数。但需要注意的是评分的匹配逻辑不能写死在视图函数里应该抽出独立的算法模块输入参数是用户ID输出是推荐房源ID列表。这样你能很方便在测试脚本里单独调试推荐效果不必每次启动Django服务才能看到结果。经验谈推荐算法模块养成分层习惯数据预处理、相似度计算、结果生成、结果缓存四层。四层之间用清晰的函数接口沟通你的代码可读性会远超同届学生。答辩被问到底层细节时你还能把每一层的设计理由讲得清清楚楚。3.3 混合推荐策略与效果验证为了展示项目亮点混合推荐策略不是简单把两个算法结果合并而是按阶段做决策新用户基于内容的推荐结果优先不依赖行为数据。老用户基于物品的协同过滤为主内容推荐作为补充兜底。热门兜底当推荐结果数量不足时用全局热门房源补足Top-N。这段决策逻辑可以用一个简单的python流程清晰地表达出来def get_recommendations(user_id, top_n10): cf_result get_cf_recommendations(user_id, top_n) if len(cf_result) top_n: content_result get_content_recommendations(user_id, top_n) combined merge_results(cf_result, content_result) return fill_with_hot_houses(combined, top_n) return cf_result混合策略的价值不仅体现在推荐效果更好还体现在答辩时可以讲清楚系统如何在不同阶段应对不同问题冷启动阶段、行为稀疏阶段、行为丰富阶段。把这个演进逻辑画成图论文的算法章节直接就立体了。关于推荐效果的验证很多同学会忽略。你可以做一个简单的离线评估把行为数据集按8:2划分训练集和测试集用准确率、召回率观察Top-N推荐命中情况。实际上只需要写几十行计算逻辑但效果评估这个环节在毕业设计论文里非常加分很多同学都没做做了就是一个突出的亮点。4. 大屏可视化设计与数据支撑4.1 大屏展示的核心思路租房大屏可视化是标题里另一个亮点。大屏吸引了眼球在答辩现场表现力极强说白了给评委的第一印象就是技术有深度、工程有完整性。但大屏并不是单纯把图表摆上去它的核心目标是让观看者在5秒内读懂平台的核心运营状态。租房行业的大屏通常聚焦这几个核心指标指标展示形式业务含义房源总数/在租数数字翻牌器平台规模累计用户数/今日访问量数字翻牌器用户活跃度各区域房源占比地图/柱状图房源空间分布租金价格区间分布直方图/饼图市场价格结构户型占比环形图供给结构近12月租金走势折线图市场趋势热门小区TOP10横向条形图用户关注焦点用户收藏/预约转化率仪表盘平台转化能力这些指标与推荐系统形成闭环推荐影响用户行为用户行为形成统计数据统计数据又反过来指导数据分析和运营决策。把这个闭环讲清楚整个毕业设计的业务逻辑就非常有说服力。4.2 大屏技术选型与图表配色可视化大屏的技术选型不需要太花哨。业界最通用的方案是ECharts 现有前端框架。ECharts在数据可视化的能力和生态成熟度上是不可撼动的选择尤其它的地图、仪表盘、关系图在租房场景里都很合适。我给出的方案是Vue脚手架里集成ECharts通过封装一个Chart组件统一管理图表的初始化、配置和销毁。不要在每个页面直接引入echarts实例而是统一封装组件你的大屏代码会整洁得多。示意实现方式如下template div refchartRef :style{ height: height px }/div /template script setup import * as echarts from echarts import { ref, onMounted, onBeforeUnmount, watch } from vue const props defineProps({ option: { type: Object, required: true }, height: { type: Number, default: 350 } }) const chartRef ref(null) let chartInstance null onMounted(() { chartInstance echarts.init(chartRef.value) chartInstance.setOption(props.option) window.addEventListener(resize, handleResize) }) onBeforeUnmount(() { if (chartInstance) { window.removeEventListener(resize, handleResize) chartInstance.dispose() } }) watch(() props.option, (newOption) { chartInstance.setOption(newOption) }, { deep: true }) /script这个组件在列表、详情页、大屏里都可以复用。关于大屏的配色方案借用行业里常用的套路深蓝色科技感背景高亮渐变色数据呈现。深蓝背景让屏幕显得有专业度亮色突出核心数据。你可以在settings里维护一份统一颜色值避免每个图表各写一套颜色导致整个屏幕风格不统一。注意ECharts的图例在数据量为0的时候会显示空白占位务必在数据源里做好空数据处理。我在做数据对接时就因为某个月没有租房订单导致折线图中断视觉效果很糟糕。处理方式是后端补全缺失月份的0值保持图表连续。4.3 大屏数据接口与前端自适应大屏数据接口需要轻量级设计。大屏通常需要每秒或每几秒刷新部分数据接口响应时间必须控制在百毫秒级别。后端的实现方式就是前面提到的建统计汇总表大屏接口只查统计表不直接查业务表。大屏的自适应布局也很关键。演示现场的屏幕可能是普通的16:9笔记本外接显示器也可能是4K大屏。我用的是rem方案以1920x1080为基准设计稿将所有尺寸转为rem配合监听窗口变化自动调整根字号。实现方式如下// 大屏适配脚本 function setRem() { const baseWidth 1920 const baseFontSize 100 const clientWidth document.documentElement.clientWidth document.documentElement.style.fontSize (clientWidth / baseWidth) * baseFontSize px } window.addEventListener(resize, setRem) setRem()使用大屏布局时我的建议是上中下左右侧栏结构顶部为核心的标题和关键数字指标中间地图或核心统计图占据最主要视觉面积左右两侧配置柱状图、趋势图、TopN榜。这种布局信息层次分明答辩演示的时候你指到哪评委就看向哪体验很舒服。5. 实操过程与环境搭建要点5.1 基础环境准备我的实操建议按下面的顺序来安装Python 3.10或以上版本创建虚拟环境安装Django、Django REST Framework、pandas、numpy等依赖。Django的版本建议选取LTS稳定版本不要追新。前端环境需要Node.js 18以上用Vue CLI或Vite脚手架创建项目安装Axios、Vue Router、Pinia、ECharts等库。这里有个非常关键的实操细节前端和后端项目不要放在同一个目录里混乱管理建议目录结构如下graduation-project/ ├── backend/ # Django后端项目 │ ├── manage.py │ ├── requirements.txt │ └── apps/ └── frontend/ # Vue前端项目 ├── package.json ├── vite.config.js └── src/前后端分离开发最尴尬的问题是端口冲突与跨域。Django默认跑在8000端口Vue默认跑在5173或8080端口端口不同必然有跨域问题。Django后端需要配置CORS方法很简单安装django-cors-headers并添加到settings的INSTALLED_APPS和MIDDLEWARE里INSTALLED_APPS [ ... corsheaders, ] MIDDLEWARE [ corsheaders.middleware.CorsMiddleware, ... ] CORS_ALLOWED_ORIGINS [ http://localhost:5173, http://127.0.0.1:5173, ]如果你用Vite开发最好在vite.config.js里配置DevServer代理这样前端请求统一走/api前缀后端无需额外处理跨域// vite.config.js export default defineConfig({ server: { port: 5173, proxy: { /api: { target: http://127.0.0.1:8000, changeOrigin: true } } } })代理这个方案的后端压力和对跨域的处理都更简单有效。开发时前端请求全部走相对路径/api/xxx生产部署时再单独处理。5.2 Django后端搭建核心流程后端搭建我建议按下面节奏走创建项目与应用配置数据库连接MySQL或SQLite都行。如果追求简单省事SQLite在演示时完全够用如果追求企业级配置的感觉可以用MySQL并给出建库脚本。我个人的建议是用MySQL因为答辩时能说使用MySQL数据库存储业务数据听起来更完整。当然如果环境安装麻烦SQLite也不丢人关键在于你的业务逻辑是否完整。之后定义数据模型并完成迁移。此时要特别重视时间字段和数据类型的定义class House(models.Model): title models.CharField(标题, max_length200) district models.CharField(区域, max_length50, db_indexTrue) address models.CharField(详细地址, max_length255) layout models.CharField(户型, max_length50) area models.FloatField(面积) price models.DecimalField(租金, max_digits10, decimal_places2, db_indexTrue) tags models.CharField(标签, max_length255) image_url models.URLField(图片地址, blankTrue) lonlat models.CharField(经纬度, max_length100, blankTrue) create_time models.DateTimeField(创建时间, auto_now_addTrue) update_time models.DateTimeField(更新时间, auto_nowTrue)需要索引的字段一定要加db_index比如区域、价格、户型。数据量一旦上来索引对查询效率的影响是立竿见影的。可视化大屏需要按区域统计不加索引的话Django后台一大查询就会卡住。REST Framework方面使用ViewSet配合ModelSerializer能大幅减少代码量。把常见的列表、详情、创建、更新逻辑交给框架默认行为自己只用重写需要定制的部分。比如房源列表需要支持多条件筛选只需重写get_queryset方法class HouseViewSet(viewsets.ModelViewSet): queryset House.objects.all() serializer_class HouseSerializer def get_queryset(self): queryset super().get_queryset() district self.request.query_params.get(district) price_min self.request.query_params.get(price_min) price_max self.request.query_params.get(price_max) layout self.request.query_params.get(layout) if district: queryset queryset.filter(districtdistrict) if price_min: queryset queryset.filter(price__gteprice_min) if price_max: queryset queryset.filter(price__lteprice_max) if layout: queryset queryset.filter(layoutlayout) return queryset.order_by(-update_time) 这样开发效率极高且代码规范。要注意的是DRF的过滤逻辑写清晰别把筛选条件全塞给前端否则接口既笨重又难测试。 ### 5.3 Vue前端搭建核心流程 前端搭建从项目脚手架开始配置路由和状态管理Pinia然后按业务模块开发页面。核心页面包括登录注册页面、首页推荐流、房源列表筛选页、房源详情页、用户个人中心、后台管理页、数据大屏。开发顺序我建议先做登录和房源列表因为这两个页面打通了前后端接口链路后面的页面开发就循着同一套调用模式。 登录模块推荐使用Token认证。前端登录成功后将Token存储到localStorage在Axios请求拦截器中放入Authorization请求头 javascript service.interceptors.request.use(config { const token localStorage.getItem(access_token) if (token) { config.headers.Authorization Bearer token } return config })Django后端配合simplejwt库做Token认证很方便又符合当前业界标准。首页的推荐列表是重头戏。完整流程是页面加载完成后请求/api/recommend/mixed?user_idxxx拿到推荐房源数据渲染房源卡片列表在列表顶部显示一行推荐理由例如根据您最近的浏览偏好为你推荐以下房源。这个细节让推荐系统在视觉上就活了起来用户在首页就能直观感受推荐与列表的区别。房源详情页同样需要展示相似房源推荐板块复用之前推荐的接口。加入看了又看的逻辑只要用户进入详情页就调用/api/recommend/similar?house_idxxx获取相似房源底部横滑展示。既增加了系统功能密度又让推荐算法在多个位置反复露脸极易在答辩时拿印象分。踩坑提醒Vue项目创建时直接选路由状态管理ESLint模板后面你就知道省了多少事。不要在项目中途再手动加Vue Router或Pinia脚手架的一次性配置远比手工补稳妥。5.4 推荐算法的数据消化问题推荐算法模块单独讲一下因为这一步是项目的核心亮点也是最大的坑。协同过滤需要用户行为数据真实环境下数据是逐步积累的但在毕业设计里你根本等不到积累你要自己写一个模拟数据生成脚本批量制造用户行为。模拟数据生成不能太无脑要遵循同样的逻辑否则推荐结果会变得很诡异。我的建议是先设定一批虚拟用户画像比如20多岁单身白领偏好明发广场附近一房一厅预算2500以内然后按照画像生成对应区域和价格偏好的行为数据和收藏记录。这么做有两个好处一是数据内在逻辑自洽推荐结果不突兀二是你可以在预测什么推荐效果后去验证结果是否符合预期。脚本用Python写运行在Django环境下直接通过ORM插入数据大致逻辑如下def generate_mock_data(user_count200, house_idsrange(1, 101)): # 生成基础行为数据 for user_idx in range(user_count): user_id ... preview_district random.choice([天河区, 白云区, 越秀区]) # 从同等区域房源抽样交互记录 candidates House.objects.filter(districtpreview_district) interacted random.sample(list(candidates), krandom.randint(8, 15)) for house in interacted: Behavior.objects.create(user_iduser_id, househouse, score...)这个环节的价值被很多同学低估了。推荐系统能否正确运转关键不是算法代码本身而是喂给算法的数据能不能反映真实场景的规律。6. 联调、安全与性能优化6.1 前后端联调的心法前后端联调是毕业设计中最容易延误工期的环节。很多团队或者单人做项目时前端接口字段跟后端不一致改来改去浪费了大量时间。我的建议是在开始写前后端代码之前先定义一份完整的API文档作为双方契约。接口路径、请求方式、请求参数、返回字段、分页结构都先定好前后端照着文档并行开发联调成本会大幅降低。前端请求统一封装后后端返回结构的一致性就非常重要。比如列表接口我建议统一一套分页格式{ code: 200, message: success, data: { total: 100, items: [ { id: 1, title: ... } ], page: 1, pages: 10 } }前端拿到这种结构后无论哪个列表页都能用同一个分页组件去处理体验相当顺滑。6.2 安全性与异常兜底毕业设计虽然不需要达到生产级安全标准但基础安全防线必须做否则答辩时会被追问如果越权访问怎么办。Django自带的安全能力要用上密码存储用Django默认的PBKDF2哈希不要明文登录认证使用JWT Token并设过期时间敏感接口在视图层加权限校验装饰器from rest_framework.permissions import IsAuthenticated class FavoriteViewSet(viewsets.ModelViewSet): permission_classes [IsAuthenticated] def get_queryset(self): return Favorite.objects.filter(userself.request.user) 这样用户只能操作自己的收藏数据越权访问直接返回403。这是答辩时一个很容易讲清楚的安全设计。 后端接口需要做全局异常处理避免Django在异常时返回HTML错误页破坏前端解析。统一异常处理器加一个所有异常就都能返回JSON结构的错误信息前端拦截器统一提示。 ### 6.3 性能优化与答辩演示体验 性能优化方面毕业设计系统有几个常见瓶颈推荐接口计算慢、大屏图表加载卡顿、房源图片体积过大。我的解决方案是 推荐接口做缓存。协同过滤计算结果不依赖实时数据完全可以每天算一次存缓存。用Django缓存框架的LocMemCache或Redis把推荐结果以userId为key存起来下次请求直接读缓存接口响应时间从数百毫秒降到个位数毫秒。 大屏数据用定时统计。前面提到的tb_statistics表每晚定时生成全量快照大屏接口只查快照页面怎么刷新都快。 房源图片压缩。不少同学直接外链很大的图片大屏加载时卡得很明显。务必压缩到合适的尺寸推荐宽度不超过800px单张50-150KB图片格式用WebP更好。 答辩现场演示的时候网络环境不稳定很常见。稳妥的做法是本地运行所有服务和数据都在本机不依赖外网。前端打包后用Nginx或直接Python起一个静态服务器这样即使现场断网也可以正常演示。 ## 7. 常见问题排查与答辩心智 ### 7.1 实战问题复盘记录 我在搭建类似项目时踩过不少坑整理成速查表给大家参考 | 问题现象 | 可能原因 | 排查/解决方式 | |----------|----------|----------------| | 前端请求报CORS错误 | 后端未配置CORS | 检查django-cors-headers配置来源是否包含前端地址 | | 推荐接口返回空列表 | 用户行为数据太少 | 增加模拟数据量用户行为保证至少10-20条 | | 大屏图表白屏 | ECharts图表高度未设置 | 容器必须有确定高度动态生成容器要算style | | 图片加载特别慢 | 原图体积过大 | 压缩图片或走CDN详情页用懒加载 | | 分页数据错乱 | 参数传递不对 | 前后端统一页码从0或1开始别混用 | | Token登录失效 | JWT过期时间太短 | 设置合理的过期时间如2小时或7天 | | 推荐效果不合理 | 数据模拟逻辑太随机 | 按照用户画像模拟数据地区、价格、户型保持内部一致 | | DRF接口报500错误 | 序列化器字段与模型不一致 | 查看控制台日志检查序列化字段是否重复 | 这些错误我全部排查过大多发生在开发中后期属于高频踩坑点。建议在项目开发到70%左右做一次完整回归测试把这些常见问题提前暴露并修复避免拖到答辩前夜。 ### 7.2 LW文档与PPT的内容支撑 毕业设计文档写作方面推荐系统类的项目文档最容易出彩的地方在于算法设计系统设计系统实现与测试三个章节。LW文档不要写成API说明书的堆砌而应该聚焦为什么这样做类图、ER图、架构图、推荐流程图、时序图这些能反映出你设计思考的图比大段代码有价值得多。 PPT的逻辑线要按业务痛点分析→系统架构设计→功能演示→推荐算法原理→可视化效果→总结展望来组织。演示时先讲场景再讲实现最后讲效果验证。答辩问答环节重点准备这几个问题推荐算法为什么选协同过滤冷启动怎么处理行为数据怎么来的大屏刷新策略是什么如果这些都能讲清楚答辩基本稳了。 关于讲解部分强烈建议在正式演示前预演两遍。第一遍走完整流程第二遍模拟评委打断追问围绕算法冷启动数据来源权限安全预演回答。很多项目不是做得不够好而是主人解说逻辑混乱、卡壳掉链子白白丢了分数。 ### 7.3 答辩时间分配与演示节奏 演示环节通常只有5-10分钟节奏控制很重要。我建议的时间分配是业务背景和意义1分钟系统架构与框架1分钟半推荐算法与数据流程1分钟半功能页面演示3分钟大屏可视化展示2分钟。这10分钟节奏紧凑但每部分都有支撑点。 演示页面上可以提前放几个高光时刻比如搜索租房时条件的实时筛选效果、推荐结果与用户历史行为的关联注释、大屏的图表交互动效。高光时刻不要多三个足够但每个都要让人印象深刻。 我个人的经验是整个毕业设计从搭建环境到答辩结束合理周期在8到10周。前两周做需求分析与架构设计中间四周做前后端开发与算法调试最后两周集中攻坚文档与PPT。即使时间紧也一定要留出至少一整周做系统测试和问题修复不要等到答辩前三天还在改代码。 ## 8. 系统完工后的使用体验实录 项目全部开发完成后有必要从用户视角做一次完整走查而不仅仅是功能能跑。我的习惯是像一个普通租客一样操作注册账号完善偏好设置点击浏览房源收藏预约看房观察每一步系统反应。 说实话第一次完整走查下来发现了不少体验问题推荐列表在夜间模式下没有做适配部分区域屏幕亮度低时看不清还出现了屏幕调整尺寸后大屏图表挤压变形的情况。这些问题单独看每个都小但合在一起就很影响整体质量印象。经过两轮走查修复后系统体验才真正趋于完整。 大屏端我额外做了一个夜间演示模式调整默认以深色背景显示所有图表保证在室内灯光偏暗的答辩环境下视觉聚焦翻牌器数字用高亮颜色动态刷新时有微弱的轮播动画增加大屏的活气。 最后和大家说个实用心得这类综合性的毕业设计项目做完和做好的差距往往不在功能数量而在细节完整度和表达的连贯性。推荐系统本身的算法模型并不复杂效果好不好很大程度上取决于数据模拟是否合理、接口设计是否规范、大屏图表是否有说服力。做的时候心里一直装着评委最想看什么这个问题所有功能取舍和代码组织都会有更明确的方向。遇到做不下去的情况时不妨把成本拆小一次只解决一个模块的小问题把环境问题、数据问题、代码逻辑问题分开排查动手写之前先花时间梳理数据结构进度反而会更快。这个项目做完之后如果你想扩展可以继续加爬虫自动采集真实房源数据、加Redis缓存优化推荐响应时间或者把大屏改成实时数据流更新这些都是不错的深挖方向。