基于Django的诗词鉴赏与交流网站设计与实现

发布时间:2026/10/15 14:11:25
基于Django的诗词鉴赏与交流网站设计与实现 又到了毕业设计选题的季节每年我都能收到大量能不能用Django做一个XX网站的咨询。今年被问得最多的题目之一就是基于Django框架和Python的诗词鉴赏与交流网站的设计与实现。老实说这个题目听起来很老牌但它覆盖面广、可深可浅反而是我最愿意展开讲的一个项目——它既能完整展示Django的核心能力又不必涉及太重的前后端分离架构做出来的成果可视性还特别强。这个网站要解决的本质问题其实很简单让用户能浏览、检索、品味古诗词同时能围绕某一首诗展开讨论、收藏、互动。它不只是把古诗词堆出来给人看的静态站而是一个有用户体系、内容运营、互动行为的社区型站点。无论你是正在选毕设题目的人还是Django学完基础想找个完整项目练手的人这篇文章应该都能帮你少走一些弯路。1. 先想清楚诗词鉴赏与交流要拆成哪些功能当一个题目落到纸面上最忌讳的就是直接开写代码。我见过太多人拿到题目后第一件事就是django-admin startproject结果写到一半发现需求完全没理清表结构返工了三次。所以第一步踏踏实实做需求拆解后续才不会翻车。1.1 内容消费、用户参与、后台管理三块怎么划分我习惯把这类网站拆成三个子模块来思考。第一是内容消费模块。诗词列表、诗词详情、按作者筛选、按朝代归类、关键词检索这些是网站的地基。用户进来第一眼要看的是内容不是你有多厉害的花哨动画。诗词详情页至少要包含原文、作者、朝代、注释、译文、赏析这些字段其中赏析是内容运营的核心也是区别于普通古诗文仓库的关键点。第二是用户参与模块。注册、登录、收藏、评论、点赞、浏览历史这些构成了交流的语义。题目里的交流最容易被人理解成站内信或者实时聊天室但实际上最贴合古典文学文化氛围、也最容易落地的是评论区讨论。围绕一首诗展开观点碰撞、补充典故、纠正注释错误这比做一个没人用的聊天室有价值得多。第三是后台管理模块。诗词数据从哪来人工录入几百首没问题上千首呢管理员需要一个好用的内容管理界面。Django自带的admin后台在这里能发挥巨大作用运营人员可以快速录入、批量修改、上下架内容不需要写一行代码。1.2 用户角色和核心故事线我不建议把用户角色写得特别复杂什么超级管理员、运营员、审核员、普通用户、游客五层权限纯属给自己找麻烦。实际项目里三类角色就够了角色能力边界典型使用场景游客浏览、检索、看评论路过搜一首诗读一读赏析觉得不错但不想注册注册用户在游客基础上增加收藏、评论、点赞、个人中心看到喜欢的诗句收藏起来在评论区写下自己的理解管理员在注册用户基础上管理诗词内容、审核评论、查看数据统计录入新诗词、处理违规评论、看每日活跃数据用故事线来验证功能是否完整会更直观。假设一位古典文学爱好者打开了网站他先按朝代筛选出宋词点进苏轼那首《水调歌头》读完赏析后在评论区看到一条关于明月几时有用典的深度讨论他觉得很有意思顺手收藏了这首词并留下了一条自己的注解。这套流程走通核心功能的骨架就算立住了。1.3 划清MVP边界别被题目带着跑每个巴子题目都恨不得把大数据、推荐算法、知识图谱都塞进去但作为项目设计第一版永远要先做最小完整闭环。我的建议是检索、详情、收藏、评论、后台内容管理这五件事是底线。像用户积分、等级勋章、排行榜、每日推荐、个人主页这些属于锦上添花有时间再做。还有一点要提醒如果题目里没有明确写人工智能算法推荐就千万别自作主张加一个基于协同过滤的推荐系统工作量翻倍而且答辩时容易被问穿。2. 技术选型的几个现实理由为什么锁死Django很多同学喜欢在选型阶段纠结半天其实这个题目几乎为Django量身定制。我来分析一下为什么。2.1 和Flask、FastAPI、Node.js对比Django赢在哪我做过一个小表格给周围的朋友做选型参考框架上手难度自带功能适合场景本项目关键需求匹配度Flask低弱什么都要自己拼轻量API、极简站点需要自己集成ORM、Admin、Auth中FastAPI中自动文档、异步高性能API服务前端全分离场景、偏接口中低Node/Express中弱生态靠NPM高并发I/O密集全JS技术栈重起炉灶低Django中高强ORM、Admin、Auth、中间件内容型网站、管理后台重的系统高Django对这个题目的匹配度是碾压级的。上来就自带一套完整的用户认证系统注册、登录、会话管理、密码加密、权限控制全都有了你只需要做少量的配置和模板适配不需要从零写登录逻辑。Admin后台更是为内容运营而生诗词数据的增删改查开箱即用。2.2 自带Admin是内容型网站的隐藏王牌诗词鉴赏网站的本质是内容驱动而内容驱动就意味着会有一个人不断往里填数据。Django Admin让内容管理者可以不用面对命令行和SQL语句直接在网页上以表格形式维护几百首诗词还能用search_fields快速搜索某个作者的全部作品。对毕设答辩来说管理员可通过后台便捷管理上数百条诗词数据这句话写进论文里极其加分而且它是真的能演示的不是画在PPT上的功能。2.3 MTV结构如何正好对接这个项目Django的MTVModel-Template-View结构听着抽象放到诗词网站里立刻清晰Model层对应诗词、用户、评论、收藏这些数据库表View层负责处理用户请求了某首诗的详情用户提交了一条评论这样的业务逻辑Template层渲染最终的HTML页面。数据从数据库到页面的流转路径是单向清晰的这特别适合做一个以CRUD为核心的网站也方便在论文里画出清晰的架构图和时序图。3. 把诗词、用户和讨论装进哪几张表建模与字段设计数据库设计是整个项目里返工率最高的部分建表建错了后面写多少代码都在打补丁。我在这套项目里总共用了六张核心表这里我一张一张讲清楚设计思路。3.1 六张核心数据表与字段设计第一张是用户表。但不要自己建直接使用Django自带的django.contrib.auth里的User模型它已经包含了用户名、密码哈希、邮箱、最后登录时间等字段。在它的基础上扩展一个Profile表用来存用户的个性签名、头像、注册时间这些附加信息即可。第二张是诗词表Poem这是全站信息密度最高的表。我用的字段大致如下class Poem(models.Model): title models.CharField(标题, max_length100) author models.CharField(作者, max_length50) dynasty models.CharField(朝代, max_length20) content models.TextField(正文) translation models.TextField(译文, blankTrue) appreciation models.TextField(赏析, blankTrue) tags models.ManyToManyField(Tag, verbose_name标签, blankTrue) created_at models.DateTimeField(auto_now_addTrue) updated_at models.DateTimeField(auto_nowTrue) class Meta: ordering [dynasty, author, id] indexes [ models.Index(fields[author]), models.Index(fields[dynasty]), ] def __str__(self): return f{self.title} - {self.author}我特意把朝代设成CharField而不是外键到一张朝代表因为古诗词的朝代就那么几个比如唐、宋、元、明、清用外键去关联反而要多做一次表连接没任何实际收益。标签用了多对多关系因为一首词可以同时属于豪放派咏月中秋等多个标签。第三张是评论区表Comment。关键点是既要把评论关联到诗歌Poem也要关联到用户User再带一个content字段和created_at字段。这里有个很常见的设计失误有人会加一个评论的评论的自关联来搞楼中楼但第一版切不要做这个做一层平铺评论就够了。第四张是收藏表Favorite。它本质上是用户和诗词之间的关联表我通常额外加一个created_at记录收藏时间用于个人中心按时间排序。第五张是标签表Tag字段极简一个name一个slug就够。第六张表是浏览记录表ViewLog这个表可能很多人忽略但它很有用——用户个人中心的最近浏览、猜你喜欢功能以及后台的内容热度统计都靠它支撑。3.2 为什么赏析内容要单独可维护做内容型网站最容易忽略的一点是诗词原文是固定的但赏析是可更新的。同一首《静夜思》不同读者不同时期理解不同运营人员可能需要不断优化赏析文本。把appreciation作为Poem表的一个字段好处是天然自然关联坏处是每次修改都要更新整条Poem记录。但考虑到项目体量这个设计完全够用不必像大型CMS那样把内容拆成版本化存储。我还额外增加了一个is_published布尔字段用于控制草稿和发布状态——这个字段可能你前期用不上但内容上千条后你就会感谢它。3.3 检索字段的隐藏设计后面要做的全文检索功能依赖的数据结构在设计阶段就得打算好。直接用content LIKE %明月%去查询在数据量小的时候没问题几百首诗根本感觉不到慢但数据超过几千条加上多字段组合筛选性能就不可控了。我这里采取的做法是在Poem表上增加两个冗余搜索字段title_search和content_search在数据录入时自动把对应文本做规范化处理去掉标点空格、统一简体。这样检索时只需要对这两个字段做icontains匹配配合数据库的索引真实体感会比裸查全表好很多。4. 从空项目到完整跑通核心功能的实现顺序与代码细节项目初始化这些基础操作我就不赘述了无非是建虚拟环境、安装Django、创建项目和app。我更想分享的是按什么顺序去实现功能才能避免反复推倒重来以及每个模块的关键代码细节。4.1 开发顺序建议先内容再用户最后互动我的推荐顺序是第一步打通诗词列表页和详情页把纯静态内容先跑起来第二步接入检索和筛选功能让用户能找到诗第三步再做注册登录和评论收藏。这套顺序的核心逻辑是把内容消费这条主链路优先打通用户系统虽然是基础但它是配角评论收藏又依赖用户系统放在最后才合理。词条列表页用Django的ListView非常简单# views.py from django.views.generic import ListView from .models import Poem class PoemListView(ListView): model Poem template_name poem_list.html context_object_name poems paginate_by 20 def get_queryset(self): queryset super().get_queryset() keyword self.request.GET.get(kw, ).strip() if keyword: queryset queryset.filter( Q(title_search__icontainskeyword) | Q(content_search__icontainskeyword) | Q(author__icontainskeyword) ) dynasty self.request.GET.get(dynasty, ) if dynasty: queryset queryset.filter(dynastydynasty) return queryset这样一次搞定关键词搜索和朝代筛选配合模板里的表单即可。分页组件我用的是Django内置的Paginator模板里手动渲染上一页下一页即可这里不再赘述。4.2 注册登录与评论Django Auth的正确打开方式注册登录直接用django.contrib.auth的login、logout、authenticate三个函数就够了。需要注意的一个细节是注册成功后要自动登录否则用户刚注册完还要再输一遍密码体验极差。注册的视图逻辑大概是from django.contrib.auth.models import User from django.contrib.auth import login, authenticate def register(request): if request.method POST: username request.POST.get(username) password request.POST.get(password) password2 request.POST.get(password2) if password ! password2: # 提示两次密码不一致 ... user User.objects.create_user(usernameusername, passwordpassword) auth_user authenticate(usernameusername, passwordpassword) login(request, auth_user) return redirect(home)提交评论时要判断用户是否登录未登录则跳转到登录页登录后才允许写评论。评论区展示时注意一次查询把评论和用户信息联查出来避免在模板循环里逐条查询用户表造成N1问题。我一般会这样优化comments Comment.objects.filter(poempoem).select_related(user)4.3 收藏功能的幂等设计收藏是个典型的点两次就是取消的交互。用户第一次点收藏Insert一条记录第二次再点同样的位置应该Delete这条记录而不是再插一条。数据库层面用UniqueConstraint约束(user, poem)唯一视图层先判断记录是否存在存在就删不存在就建from django.db.models import UniqueConstraint class Favorite(models.Model): user models.ForeignKey(User, on_deletemodels.CASCADE, verbose_name用户) poem models.ForeignKey(Poem, on_deletemodels.CASCADE, verbose_name诗词) created_at models.DateTimeField(auto_now_addTrue) class Meta: constraints [ UniqueConstraint(fields[user, poem], nameunique_user_poem) ]4.4 Admin后台定制让运营者友好录入诗词Admin后台的定制是这个项目的重头戏。我的做法是在admin.py里把常用查询字段全部暴露出来from django.contrib import admin from .models import Poem admin.register(Poem) class PoemAdmin(admin.ModelAdmin): list_display (title, author, dynasty, created_at, updated_at) list_filter (dynasty,) search_fields (title, author, content) list_per_page 50这样管理者在后台直接按朝代筛选通过搜索框快速定位某位作者的全部作品点进去就能编辑。数据录入的效率比直接操作数据库不知道高到哪里去了。这里强烈建议配一个批量导入脚本可以把Excel表里的诗词数据读出来转成Poem实例几百条数据几分钟就能倒进去。5. 我在这套网站上踩过的坑和绕过的弯任何项目跑通后回头整理一遍踩坑记录都是价值最高的部分。我把这几个坑记录下来希望你能直接绕开。5.1 中文搜索体验稀碎分词问题比想象中严重第一次做搜索功能时我天真地以为用icontains加数据库索引就够了。实际测试时输入月匹配没问题但输入明月之后一些内容是月明或中间插入了其他字的诗词就匹配不到了更别提一些译文里包含异体字的情况。后来我做了一个折衷方案在录入时把诗词正文做了清洗去掉所有标点符号并在数据库层面对content_search建立索引检索时同样先把输入的关键词做清洗再去匹配。这样虽然不解决语义搜索这种高级问题但传统文学网站最常见的按关键词找诗句场景已经够用。5.2 分页时查询参数丢失列表页如果同时有kw明月和dynasty宋两个参数翻到第二页时只保留了page2关键词和朝代筛选全部丢失点击下一页看到的是没有过滤的完整列表。这个bug很隐蔽因为它只在筛选状态翻页同时发生时出现。问题根源在于模板里分页链接生成时没有把现有query参数拼接进去。解决方案是视图中打包参数时把当前请求的所有GET参数带上页面URL长一点没关系功能要正确。5.3 静态文件404的经典陷阱开发环境一切正常一部署就发现CSS全没了。问题十有八九在DEBUGFalse时Django默认不再帮你提供静态文件服务。所以部署前必须收集静态文件配置STATIC_ROOT、STATIC_URL再让Nginx去托管静态目录这是一个此前没跑过正式环境的人一定会踩的坑。还有一个不那么明显的问题在开发阶段用runserver时如果访问的是非根路径模板里用绝对路径/static/css/style.css没问题但用了相对路径就可能导致找不到资源所以模板里写静态资源地址一定要用{% static %}标签或从根路径开始写。5.4 数据导入时的不规范内容从网上下载的古诗词数据集质量参差不齐有的有错别字有的空行没清理有的作者名带了奇怪的全角空格。我在写导入脚本时加入了校验空字段自动跳过标题里包含换行符自动清除朝代字段不在白名单里的归为其他。另外设置了一个--dry-run参数可以先预跑一遍输出统计信息确认无误后再真正写入数据库。这些细节听起来平平无奇但确实救过我一次——有一批数据里将近三分之一带有导出工具生成的冗余日志文字差点污染了整个库。6. 本地能跑不等于能上线部署与安全检查清单把项目从开发机搬到服务器往往是整个项目环节里被最多人忽略、也最容易出问题的环节。我把部署相关的思考压缩成一份可以直接照做的清单。6.1 settings配置的环境分离我强烈建议从一开始就把settings.py拆成base.py、dev.py、prod.py三个文件。base.py放公共配置dev.py放调试期配置prod.py专门放生产环境的SECRET_KEY、ALLOWED_HOSTS、DEBUG False这些。不要觉得麻烦等你上线部署时就知道有多省心。尤其是数据库密码和SECRET_KEY这种敏感信息务必通过环境变量注入不能让它们以明文形式出现在代码里。曾经有大量线上项目因为SECRET_KEY泄漏导致会话被伪造这个教训在安全领域反复被提起。6.2 gunicorn加Nginx的经典组合这是目前最成熟稳定的部署姿势。业务代码由Gunicorn作为WSGI服务器托管Nginx负责反向代理和静态文件托管。我没有采用Windows服务器上常用的等待Perl之类的方案因为那是把方钉子往圆洞里砸。Nginx配置文件要关注两个关键点第一是把/static/和/media/两个路径直接映射到磁盘目录减少对Python进程的请求压力第二是配置合理的超时参数proxy_read_timeout如果设太短用户提交长评论时可能超时返回502。6.3 登录安全与评论内容清洗上线环境与开发环境最大的差异是暴露在公网上会被各种扫描工具扫。我做的几件最基础但有效的事是登录接口限制频率防止暴力猜密码评论提交时过滤掉带script标签的内容用bleach这类库做标签白名单清洗防止存储型XSSAdmin后台路径从默认的/admin/改成语义无关的路径虽然不能防内鬼但能过滤掉绝大多数自动化扫描流量。6.4 上线前的自检清单我把每次部署前都会过一遍的检查事项列在下面检查项操作达标标准DEBUG开关确认prod.py中为False不再显示详细报错堆栈ALLOWED_HOSTS填入域名/IP不能漏配导致403静态文件运行collectstatic并确认Nginx可访问页面无样式丢失数据库备份生产库手动dump一份文件可正常恢复定时任务如果有内容更新脚本确认Celery或cron已配置任务能自动执行日志确认Django日志已输出到文件出错时有迹可循最后聊几句做完这个项目我最大的体会是Django这种大而全的框架其实特别适合练手和做毕设它把很多你不想操心的脏活累活都预先做好了你反而能把精力集中在业务设计和交互体验上。回顾整个开发过程我自己收获最大的不是写了多少行代码而是经历了从需求拆解、建模、编码、测试、部署这一整条完整的工程链路。一个小建议给正在做类似网站的朋友数据质量比功能数量更重要。哪怕你的功能只有诗词浏览和评论区只要选的诗、赏析文本、作者信息都准确规范用户打开后觉得内容可靠你这个网站就已经赢过了八成功能花哨但内容粗制滥造的项目。先通过Admin后台认认真真录入三五十首打磨过的诗词再开始调前端样式你会发现整个系统的质感立刻不一样。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询