在没有互联网的年代,我们用日记来记录每天的心得体会。小的时候我有一个带锁的日记本,生怕被别人看见里面写了啥,钥匙藏得那叫一个绝。

现在时代变了,网络版的日记本:博客,却巴不得越多人看越好。

别人看完你写的深度好文,难免也想高谈阔论一番,这就是“评论”功能。

本章将要编写的评论模块,几乎没有新的知识点,而是将前面章节内容的综合应用。

强烈建议读者自行尝试编写这部分内容,测试自己的知识掌握程度。

准备工作

评论是一个相对独立的功能,因此新建一个评论的app:

(env) E:\django_project\my_blog > ppython manage.py startapp comment
复制代码

有的人觉得奇怪,没有博文就没有评论,为什么说评论是“独立”的功能?

那是因为不仅博文可以评论,照片、视频甚至网站本身都可以“被评论”。将其封装成单独的模块方便以后的扩展。

确认app创建成功后,记得在settings.py中注册:

my_blog/settings.py...
INSTALLED_APPS = [...'comment',
]
...TIME_ZONE = 'Asia/Shanghai'...
复制代码

因为我们想显示发表评论的时间,修改时区设置TIME_ZONE为上海的时区。

然后在my_blog/urls.py中注册根路由:

my_blog/urls.py...
urlpatterns = [...# 评论path('comment/', include('comment.urls', namespace='comment')),
]
...
复制代码

编写核心功能

评论的模型

首先编写评论的模型:

comment/models.pyfrom django.db import models
from django.contrib.auth.models import User
from article.models import ArticlePost# 博文的评论
class Comment(models.Model):article = models.ForeignKey(ArticlePost,on_delete=models.CASCADE,related_name='comments')user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='comments')body = models.TextField()created = models.DateTimeField(auto_now_add=True)class Meta:ordering = ('created',)def __str__(self):return self.body[:20]
复制代码

模型中共有2个外键:

  • article是被评论的文章
  • user是评论的发布者

别忘了每次新增、修改Model后,必须数据迁移

提示:你必须先在setting.py中注册app,这个app中的数据迁移才能生效

评论的表单

用户提交评论时会用到表单,因此新建表单类:

comment/forms.pyfrom django import forms
from .models import Commentclass CommentForm(forms.ModelForm):class Meta:model = Commentfields = ['body']
复制代码

因为模型中的2个外键将通过视图逻辑自动填写,所以这里只需要提交body就足够了。

评论的url

在comment app中新建路由文件:

comment/urls.pyfrom django.urls import path
from . import viewsapp_name = 'comment'urlpatterns = [# 发表评论path('post-comment/<int:article_id>/', views.post_comment, name='post_comment'),
]
复制代码

评论必须关联在某篇具体的博文里,因此传入博文的id,方便后续调用。

post_comment()视图还没写,先取个名字占位置。

评论的视图

评论的视图函数如下:

comment/views.pyfrom django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required
from django.http import HttpResponsefrom article.models import ArticlePost
from .forms import CommentForm# 文章评论
@login_required(login_url='/userprofile/login/')
def post_comment(request, article_id):article = get_object_or_404(ArticlePost, id=article_id)# 处理 POST 请求if request.method == 'POST':comment_form = CommentForm(request.POST)if comment_form.is_valid():new_comment = comment_form.save(commit=False)new_comment.article = articlenew_comment.user = request.usernew_comment.save()return redirect(article)else:return HttpResponse("表单内容有误,请重新填写。")# 处理错误请求else:return HttpResponse("发表评论仅接受POST请求。")
复制代码

代码中有2个新面孔。

get_object_or_404():它和Model.objects.get()的功能基本是相同的。区别是在生产环境下,如果用户请求一个不存在的对象时,Model.objects.get()会返回Error 500(服务器内部错误),而get_object_or_404()会返回Error 404。相比之下,返回404错误更加的准确。

redirect():返回到一个适当的url中:即用户发送评论后,重新定向到文章详情页面。当其参数是一个Model对象时,会自动调用这个Model对象的get_absolute_url()方法。因此接下来马上修改article的模型。

实际上之前的章节已经用过redirect()了。功能是相同的,实现上略有区别。

文章的模型

按照上面说的,在文章模型中添加get_absolute_url()方法:

article/models.py...
# 记得导入
from django.urls import reverseclass ArticlePost(models.Model):...# 获取文章地址def get_absolute_url(self):return reverse('article:article_detail', args=[self.id])
复制代码

通过reverse()方法返回文章详情页面的url,实现了路由重定向。

文章详情视图

评论模块需要在文章详情页面展示,所以必须把评论模块的上下文也传递到模板中。

因此修改article/views.py中的article_detail()

article/views.py...from comment.models import Commentdef article_detail(request, id):# 已有代码article = ArticlePost.objects.get(id=id)# 取出文章评论comments = Comment.objects.filter(article=id)...# 添加comments上下文context = { 'article': article, 'toc': md.toc, 'comments': comments }...
复制代码

filter()可以取出多个满足条件的对象,而get()只能取出1个,注意区分使用

文章详情模板

到最后一步了,坚持。所有后台的功能已经写完了,就差把所有这些展现到页面中了。

修改文章详情页面:

templates/article/detail.html...<div class="col-9">...<!-- 已有代码,文章正文 --><div class="col-12">...</div><!-- 发表评论 --><hr>{% if user.is_authenticated %}<div><form action="{% url 'comment:post_comment' article.id %}" method="POST">{% csrf_token %}<div class="form-group"><label for="body"><strong>我也要发言:</strong></label><textarea type="text" class="form-control" id="body" name="body" rows="2"></textarea></div><!-- 提交按钮 --><button type="submit" class="btn btn-primary ">发送</button>                    </form></div><br>{% else %}<br><h5 class="row justify-content-center">请<a href="{% url 'userprofile:login' %}">登录</a>后回复</h5><br>{% endif %}<!-- 显示评论 --><h4>共有{{ comments.count }}条评论</h4><div>{% for comment in comments %}<hr><p><strong style="color: pink">{{ comment.user }}</strong> 于 <span style="color: green">{{ comment.created|date:"Y-m-d H:i:s" }}</span> 时说:</p><pre style="font-family: inherit; font-size: 1em;">
{{ comment.body }}</pre>{% endfor %}</div>
</div><!-- 目录 -->
<div class="col-3 mt-4">...
</div>...
复制代码
  • 表单组件中的action指定数据提交到哪个url中

  • 显示评论中的comments.count是模板对象中内置的方法,对包含的元素进行计数

  • |date:"Y-m-d H:i:s":管道符你已经很熟悉了,用于给对象“粘贴”某些属性或功能。这里用于格式化日期的显示方式。请尝试修改其中的某些字符试试效果。

  • <pre>定义预格式化的文本,在我们的项目中最关键的作用是保留空格和换行符。该标签会改变文字的字体、大小等,因此用style属性重新定义相关内容。尝试将<pre>替换为div,输入多行文本试试效果。

    之前说代码最好不要复制粘贴,否则有些“小坑”你是留意不到的。比如在<pre>标签中的文本千万不能缩进。

测试

又到了激动人心的测试环节了。

登录自己的账户,进入某个文章详情页面,发现已经可以进行留言了:

如果退出登录,显示提示语:

点击登录就回到登录页面。

评论模块的发布、展示功能就搞定了。

扫尾工作

数据的删、改功能我们已经做过很多遍,这里不打算再赘述了。

评论同样也可以支持Markdown语法,或者插入Emoji表情符号。

读者可以自己去实现感兴趣的功能。

有些网站干脆就没有删除、更新评论的功能。因为对小站来说,这些功能用到的次数太少太少了,不如把精力用在更有价值的地方去。比如我的博客就没有。

还有的网站提供软删除,删除后仅仅是不显示而已,实际上数据还存在。

具体应该如何做,都以你的喜好而定。

总结

本章实现了发表评论、展示评论的功能。像开头说的一样,本章的内容是前面所学章节的综合。

如果你没有看本章代码,而是完全靠自己完成了评论功能,那么恭喜你获得了**“Django入门程序员”**的称号!不要小看“入门”两字,万事开头难嘛。

  • 有疑问请在杜赛的个人网站留言,我会尽快回复。
  • 或Email私信我:dusaiphoto@foxmail.com
  • 项目完整代码:Django_blog_tutorial

转载请注明出处。

转载于:https://juejin.im/post/5c2c2358f265da61273d7d0c

Django搭建个人博客:在博文中发表评论相关推荐

  1. 10分钟利用django搭建一个博客

    以前老是听说ROR开发有多快多块,网上还有朋友为了证明这,专门制作了10分钟利用rails框架搭建一个简易博客的教程,最近学习django框架,觉得django给开发者的便捷也很多,心血来潮来写个10 ...

  2. Django搭建个人博客:用django-notifications实现消息通知

    凭借你勤奋的写作,拜读你文章的用户越来越多,他们的评论也分散在众多的文章之中.作为博主,读者的留言肯定是要都看的:而读者给你留言,自然也希望得到回复. 怎么将未读的留言呈现给正确的用户呢?总不能用户自 ...

  3. Django搭建简易博客

    Django简易博客,主要实现了以下功能 连接数据库 创建超级用户与后台管理 利用django-admin-bootstrap美化界面 template,view与动态URL 多说评论功能 Markd ...

  4. django项目转pyc_Python自动化运维系列:Django搭建小博客

    如何使用Django和Python怎么搭建一个小博客呢? 这是一个简单而困难的问题.简单的原因是,只要做过一次,基本上就能做到举一反三: 困难的原因是有没有用心和耐心去完成这个实验. 如果你成功了,那 ...

  5. 用django搭建个人博客(一)

    用django2.0搭建个人博客 博客网站的需求与规划 该个人博客为简单的入门示范网站,具有以下功能 项目名称为mblog 通过admin管理界面发帖.编辑以及删除贴文,且此界面支持markdown语 ...

  6. django搭建个人博客(一)

    准备阶段 首先熟悉项目的根本流程,下面是对项目的每个模块流程阶段具体分析 模块 功能 注册 图形验证.短信验证 登陆 状态保存.cookie.session 个人中心 图片上传.更新数据 发布博客 数 ...

  7. html 两个idv上下居中,Django搭建个人博客:回到顶部浮动按钮、矢量图标、页脚沉底和粘性侧边栏...

    本章集中介绍四个重要的小功能:回到顶部浮动按钮.矢量图标.页脚沉底和粘性侧边栏. 这几个功能与Django基本没啥关系,更多的是前端知识,但是对博客网站都很重要,问的读者也比较多,因此也集中讲一下好了 ...

  8. Django搭建个人博客Blog-Day05

    创建文章模块 创建文章app 在虚拟环境中,apps路径下使用如下代码: # 进入虚拟环境 workon wsl # 进入要创建app的路径下 cd blog/blog/apps # 创建app py ...

  9. 新手学习——用django搭建个人博客_day2

    一.模型设计 任何一个产品,最开始应该就是设计数据模型,模型设计好一般就不会轻易去修改它了,但是在此处,我们暂时不考虑用户登录评论这些,只考虑博客展示需要的模型.对应的表应该为以下: 博客:标题 作者 ...

最新文章

  1. python代码大全p-代码这样写更优雅(Python版)
  2. 网络嗅探与欺骗(FTP部分)
  3. 剑指Offer #08 跳台阶(递推)
  4. Python中的ThreadLocal变量
  5. docker拷贝文件
  6. 后端技术:SpringBoot配置热加载工具(devtools)笔记
  7. ASP.NET Core MVC压缩样式、脚本及总是复制文件到输出目录
  8. 在Visual Studio中利用NTVS创建Pomelo项目
  9. 论文浅尝 | 打通推荐系统与知识图谱: 第一个公开的大规模链接数据集合
  10. 高级Java面试题,你敢挑战吗?
  11. 【今日CS 视觉论文速览】20 Dec 2018
  12. bzoj 1607: [Usaco2008 Dec]Patting Heads 轻拍牛头
  13. mos 控制交流_小米智能排插的220V交流电压信号的开关控制电路设计
  14. 在vmware server中部署linux redhat 5.4 ORACLE RAC11g +ASM
  15. java每隔一小时fullgc_JVM菜鸟进阶高手之路六(JVM每隔一小时执行一次Full GC)
  16. Web前端开发最佳实践(7):使用合理的技术方案来构建小图标
  17. Vensim系统建模论文阅读-Information diffusion through social networks: The case of an online petition
  18. Android 自定义仪表盘
  19. 【解锁】Pandoc——Pandoc安装、使用、快速上手
  20. 多张图片怎么同时修改dpi?教你一键批量修改图片dpi

热门文章

  1. Artifactory7安装流程
  2. android+矢量图+插件,如何玩转Android矢量图VectorDrawable
  3. 七牛直播demo链接
  4. 设计一个三阶巴特沃斯滤波器_巴特沃斯滤波器matlab实现
  5. 第七课 淘宝客站群赚钱详解
  6. 第十七章 类关键字 - DependsOn
  7. 1、Tomcat 9安装、配置与调优--CentOS 7
  8. 在windows下IIS管理器,网站报401.2错误解决办法
  9. Candy Sharing Game
  10. python3论坛_Python3 爬虫实战 — 虎扑论坛步行街