多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

Django实战:42文件源码拆解课程推荐与智能问答系统

Django实战:42文件源码拆解课程推荐与智能问答系统 简介这份资源是一套基于Python的实时课程教学数据内容推荐与个性化智能问答系统源码面向教育技术方向的学习者、课程设计开发者及毕业设计选题人群用于解决教学资源个性化推送与知识问答自动化的实现问题。压缩包共54个文件约108KB以40个Python源文件为核心覆盖推荐算法、文本预处理、搜索与JWT鉴权等模块8个XML与1个iml文件用于IDE及数据源配置另含sqlite3数据库、txt说明与gitignore版本控制文件整体结构清晰、便于二次开发。系统围绕实时推荐、个性化学习路径与智能问答三条主线展开涉及数据挖掘、推荐算法与自然语言处理等关键技术并配有Celery异步任务与MongoDB模型等工程化实现。目前已有344人学习下载适合希望理解教育推荐系统完整链路、参考目录组织与模块划分的读者研读借鉴。1. 从一份 42 文件的 Django 源码说起实时推荐与智能问答到底怎么落地如果你手头正缺一个能跑通「课程内容推荐 智能问答」的 Python 后端骨架这份 42 个文件的 Django 工程值得拆一遍。它不是玩具 demo而是把用户登录鉴权、课程数据建模、文本预处理、推荐计算、问答检索、异步任务这几条链路都铺开了Login应用管认证course应用管课程与推荐mycelery管异步utils里塞了加密和 JWT。技术栈是 Django SQLite MongoDB 双存储 Celery前端交互靠 DRF 序列化输出。适合谁想学推荐系统怎么嵌进真实 Web 工程的后端同学以及要交课程设计、需要一份结构完整可二次开发的源码的从业者。下面按「能跑起来 → 推荐链路 → 问答链路 → 异步与坑」的顺序拆。2. 把工程跑起来环境、双数据库与启动顺序2.1 依赖清单与 Python 版本选择拿到源码第一步不是急着runserver而是先看requirements.txt和settings.py里的数据库配置。这份工程用了 Django、DRF、Celery、MongoEngine 这几类库SQLite 存关系型数据用户、课程、问答记录MongoDB 存课程正文这类非结构化文本。Python 版本建议 3.83.10太新的 3.12 上部分老版本 Celery 和 MongoEngine 会有兼容告警这是我踩过的坑。# 建虚拟环境隔离依赖别污染全局 python -m venv venv # Linux/macOS source venv/bin/activate # Windows venv\Scripts\activate # 安装依赖建议加国内镜像加速 pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple逻辑说明虚拟环境是为了避免 Django 版本冲突这类课程设计源码往往锁定了特定 Django 大版本。参数说明-i指定镜像源国内直连 PyPI 经常超时这一步能省不少等待。装完先pip list核对 Django 版本和settings.py里INSTALLED_APPS引用的第三方 app 是否匹配。2.2 数据库初始化与迁移工程里带了db.sqlite3说明作者已经把迁移跑过一遍。但直接用它有风险——里面可能有测试脏数据。我一般会重建保证干净。# 先备份原库后悔药先备好 cp db.sqlite3 db.sqlite3.bak # 生成并执行迁移如果 models 有改动 python manage.py makemigrations python manage.py migrate # 创建后台管理员方便看数据 python manage.py createsuperuser逻辑说明makemigrations根据models.py生成迁移脚本migrate落到数据库。参数说明如果makemigrations报「No changes detected」说明模型和现有迁移一致属正常。MongoDB 那边不走 Django 迁移靠mongo_models.py里的文档类定义启动前确认本地 MongoDB 服务已开连接串在settings.py里找MONGO相关配置。2.3 启动顺序先 Mongo 再 Celery 最后 Django这是最容易翻车的地方。mycelery/main.py是 Celery 入口sms/tasks.py里是异步任务。如果先起 Django 再起 Celery任务队列里的消息可能丢。# 1. 确认 MongoDB 已启动默认 27017 # 2. 启动 Celery worker celery -A mycelery.main worker -l info # 3. 另开终端启动 Django python manage.py runserver 0.0.0.0:8000逻辑说明Celery worker 要先于 Web 服务就绪才能接住 Django 抛过来的异步任务。参数说明-A mycelery.main指定 Celery app 实例位置-l info是日志级别调试期用 info生产换 warning。0.0.0.0:8000让局域网内其他机器也能访问方便前端联调。3. 推荐链路拆解从文本预处理到 recommend.py 的调用3.1 text_preprocessing.py 里做了什么推荐质量的上限由文本预处理决定。course/service/text_preprocessing.py和hit_stopwords.txt是配套的前者做分词、去停用词、清洗后者是停用词表。常见做法是用 jieba 分词再过滤掉「的、了、是」这类无意义词最后把课程描述转成词向量或 TF-IDF 矩阵。# 伪代码示意实际以源码 text_preprocessing.py 为准 import jieba def load_stopwords(path): # 逐行读停用词去掉换行 with open(path, encodingutf-8) as f: return set(line.strip() for line in f) def preprocess(text, stopwords): # 精确模式分词过滤停用词和单字 words jieba.lcut(text) return [w for w in words if w not in stopwords and len(w) 1]逻辑说明load_stopwords把hit_stopwords.txt读成集合查找是 O(1)比列表快。preprocess里len(w) 1过滤单字因为单字噪声大。参数说明jieba 的lcut是精确模式如果课程标题短、想召回更多可换cut_for_search。停用词表可以按业务补充比如把「课程」「教学」这类高频但无区分度的词加进去。3.2 recommend.py 的推荐策略与调用入口course/service/recommend.py是推荐核心。这类课程设计常见两种策略基于内容的相似度TF-IDF 余弦和基于协同过滤用户-课程评分矩阵。源码里大概率是前者因为不需要大量用户行为数据就能跑。调用入口在course/views.py通过 DRF 的 APIView 暴露出去。# 调用示意在 views 里拿到推荐结果 from course.service.recommend import get_recommendations class RecommendView(APIView): def get(self, request): user_id request.user.id # 传入用户 id返回推荐课程列表 result get_recommendations(user_id, top_n10) return Response({data: result})逻辑说明视图层只做参数校验和结果包装推荐逻辑全在 service 层这是好的分层习惯。参数说明top_n控制返回条数太大影响响应时间一般 1020。如果get_recommendations内部查 MongoDB注意加索引否则课程一多就慢。想验证推荐是否生效可以造两个兴趣不同的用户看返回列表差异是否明显。3.3 实时性怎么保证缓存与增量更新标题里的「实时」不是指毫秒级而是用户行为发生后推荐能较快反映。常见做法是用户看完一门课就写一条行为记录推荐时把最近行为加权。如果每次请求都全量算性能扛不住所以一般加缓存。# 用 Django 缓存存推荐结果设短过期时间 from django.core.cache import cache def get_recommendations(user_id, top_n10): key frec_{user_id}_{top_n} cached cache.get(key) if cached: return cached result compute_recommendations(user_id, top_n) # 缓存 5 分钟平衡实时性和性能 cache.set(key, result, 300) return result逻辑说明先查缓存命中直接返回没命中才算并回写。参数说明300是过期秒数太短起不到缓存作用太长实时性差5 分钟是常见折中。用户产生新行为时可以主动cache.delete(key)让缓存失效这就是「实时」的落点。4. 智能问答链路search.py 与问答数据建模4.1 问答检索的实现思路course/service/search.py负责问答检索。教育场景的问答通常不是生成式而是检索式把用户问题预处理后去问答库里匹配最相似的已有问题返回对应答案。这样可控、不会胡说。匹配靠的是文本相似度和推荐链路共用预处理逻辑。# 检索示意算相似度取 top1 from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics.pairwise import cosine_similarity def search_answer(question, qa_list): corpus [q[question] for q in qa_list] [question] vec TfidfVectorizer().fit_transform(corpus) # 最后一行是用户问题和前面每个库问题算相似度 sims cosine_similarity(vec[-1], vec[:-1])[0] idx sims.argmax() # 相似度太低就返回兜底话术别硬答 if sims[idx] 0.3: return {answer: 暂时没有找到相关答案请换个问法} return qa_list[idx]逻辑说明把所有库问题加用户问题一起向量化保证词表一致。参数说明0.3是相似度阈值低于它就认为没匹配上这个值要按实际语料调太高会漏答太低会答非所问。argmax取最相似的一条如果想返回多条可改成排序取前 k。4.2 问答数据的存储与序列化问答数据存在哪关系型库存问答对的结构问题、答案、课程 idMongoDB 存长文本答案或富文本。course/serializers.py负责把模型对象转成 JSON 给前端。mongo_models.py定义 Mongo 文档结构。# DRF 序列化器示意 from rest_framework import serializers class QAItemSerializer(serializers.Serializer): question serializers.CharField() answer serializers.CharField() course_id serializers.IntegerField()逻辑说明用Serializer而非ModelSerializer因为数据可能来自 Mongo 文档而非 Django 模型。参数说明字段类型要和实际数据对齐course_id用整型方便前端做关联跳转。如果答案字段可能为空加requiredFalse。4.3 登录鉴权JWT 与 utils 里的加密Login应用和utils/jwt.py、utils/encrpty.py源码里拼写如此负责认证。问答和推荐接口都需要登录态否则拿不到 user_id。JWT 的常见流程是登录成功签发 token后续请求带在 header 里。# 请求时带上 token # headers: {Authorization: Bearer token}逻辑说明utils/jwt.py里应该有签发和校验两个函数verify.py做中间件或装饰器校验。参数说明token 过期时间在签发时设教育系统一般 17 天。注意encrpty.py这个文件名是拼写错误但不影响运行二次开发时别被绕晕。5. 避坑与排查这份源码最容易翻车的五个点5.1 现象runserver 报 ModuleNotFoundError原因requirements.txt没装全或者虚拟环境没激活装到了全局。解决确认which python指向 venv再pip install -r requirements.txt缺哪个补哪个别手动一个个装。5.2 现象Celery 任务一直 pending 不执行原因worker 没起或 broker 配置不对。这份工程 broker 可能用 Redis 或 RabbitMQmycelery/config.py里找配置。解决先确认 broker 服务在跑再核对config.py里的连接串最后看 worker 日志有没有报连接拒绝。5.3 现象MongoDB 连接超时原因本地没装 MongoDB或settings.py里 host 写的是远程地址。解决本地装一个 MongoDB 社区版默认 27017把配置改成localhost。如果坚持用远程确认网络可达和认证信息。5.4 现象推荐结果每次都不一样或为空原因缓存没清导致拿到旧结果或用户行为数据为空导致算不出。解决先清缓存cache.clear()再确认该用户有没有行为记录。新用户冷启动可以走热门课程兜底别直接返回空。5.5 现象中文分词乱码原因hit_stopwords.txt编码不是 UTF-8或读取时没指定编码。解决用编辑器把文件另存为 UTF-8读取时显式写encodingutf-8。Windows 下默认 GBK这是高频坑。6. 二次开发进阶把推荐换成协同过滤并验证效果跑通只是起点真正有价值的是知道怎么改。这份源码的推荐是内容相似度想升级成协同过滤核心是把「用户-课程」交互矩阵建起来。course/models.py里如果有学习记录表就能拿到隐式反馈。# 用 surprise 或手写余弦做协同过滤的骨架 import numpy as np def user_cf(user_id, user_item_matrix, top_n10): # 算用户间相似度 sim cosine_similarity(user_item_matrix) uid user_id # 取最相似的 k 个用户 similar_users np.argsort(sim[uid])[::-1][1:6] scores {} for u in similar_users: for item, rating in enumerate(user_item_matrix[u]): if rating 0 and user_item_matrix[uid][item] 0: scores[item] scores.get(item, 0) sim[uid][u] * rating # 按得分排序取前 top_n return sorted(scores, keyscores.get, reverseTrue)[:top_n]逻辑说明先算用户相似度矩阵找邻居再用邻居的评分加权预测目标用户没看过的课程。参数说明[1:6]取相似度第 2 到第 6 名排除自己邻居数 k 一般 520太少不准太多引入噪声。验证方法留出一部分交互做测试集看推荐命中率别凭感觉说「效果好」。对比项内容推荐原版协同过滤进阶数据需求课程文本即可需要用户行为冷启动较好较差可解释性强弱实现复杂度低中改完记得把recommend.py的调用入口保持不变只换内部实现这样视图层不用动。我一般会先在本地用小批量数据跑通确认没报错再上真实数据。从那以后我每次改推荐逻辑都强制先跑一遍冷启动和新用户两条用例确认兜底没崩才敢提交。希望帮到你。本文还有配套的精品资源点击获取
返回列表