评论列表与评论树
功能介绍:
主要有两部分:显示评论和评论提交评论
其中显示评论有两种实现render显示与Ajax实现,提交也一样
评论楼
1.评论楼render数据
浏览器render显示取出文章对应的评论,浏览器渲染
2.对楼层的回复标签进行操作
a.在·回复标签·中动态绑定`楼层用户`,`楼层用户ID值`
b.为回复按钮绑定事件,首先获得`评论文本框`的焦点,
c.在文本框中将`@楼层用户`添加到文本框中,
d.将楼层用户ID值赋给全局变量`parent_id`
3.提交按钮绑定事件
成功添加信息后对提交按钮绑定事件,使用Ajax向服务器传值,需要传递的值有楼层parent_id-楼层ID,content-评论内容,article_id-文章ID
判断
content是否为空判断
parent_id是否为空,如果为空直接传content,不为空先将@用户名过滤后再进行传值通过Ajaxu将数据传到服务器,先对
parent_id进行判断,如果不为空在评论表中添加一条数据,同时更新文章表数据;parent_id为空同样添加,但此时这条评论为根评论添加数据完成后,返回序列化字典(JsonResponse),
ret = {'state':False}其中state是表示添加数据是否发生异常在
Ajax中处理服务器传回的数据,state为真添成功,成功后的操作可以刷新页面(render)或者评论楼下动态添加一条记录(Ajax)render实现很容易不在复述;Ajax实现需要的楼层可以根据需要定制,如果需要访问时间(成功添加数据完成后返回值为添加数据对像,取出时间放入字典),楼层数(在渡浏览器获得即可),回复用户(当前登录用户),内容(服务器返回数据)等,需要注意的是如果传回的数据类型是JSON时需要进行转换(d.条中的字典可以按需要添加)Ajax实现评论楼时数据构建时需要拼接字符串,可以使用ECMAScript 6.0(以下简称ES6)实现,然后清空评论文本框内容,清空全局变量parent_id
评论树
- 加载相关文章数,据使用
Ajax - 使用
JS对文章数据进行处理,对父ID进行判断,如果有父ID将数据添加到对应的标签下,没有父ID作为根评论显示到页面上
添加新评论会有几个BUG:
1.点击回复提交后,不刷新页面再次提交一条评论
第一条BUG的解决方案为提交评论后清空`pid`
2.点击回复手动删除@对象再手写入新的评论人
第二条的这个需要匹配回复这篇文章的评论的用户,是否在回复表中
涉及知识点
Ajax的知识运用的很多,$.each(),.indexOf(""),slice(),append(),.attr(),function()(),ECMAScript 6.0
ECMAScript 6.0的简单使用
示例代码
html代码
评论列表
<ul class="comment-list list-group">
{ % if comment_list % }
<p>评论列表</p>
{ % for comment in comment_list % }
<li class="comment-item list-group-item">
<div class="comment-title">
<a href="javascript:void(0)">#{ { forloop.counter } }楼</a>
<span>{ { comment.create_time|date:"Y-m-d H:i" } }</span>
<a href="/blog/{ { comment.user.username } }">{ { comment.user.username } }</a>
{ % if comment.user.pk != request.user.pk % }
<span class="pull-right comment-reply" username="{ { comment.user.username } }"
pk="{ { comment.pk } }">
<a href="javascript:void(0)">回复</a>
</span>
{ % else % }
<span class="pull-right comment-update" username="{ { comment.user.username } }"
pk="{ { comment.pk } }">
<span><a href="javascript:void(0)">修改</a> </span>
<span><a href="javascript:void(0)">删除</a></span>
</span>
{ % endif % }
</div>
<div class="comment-body">
{ % if comment.parent_comment_id % }
<p>@{ { comment.parent_comment.user.username } }</p>
{ % endif % }
{ { comment } }
</div>
</li>
{ % endfor % }
<hr>
{ % endif % }
</ul>
评论树
<p>评论树</p>
<div class="comment_tree"></div>
JS代码
评论楼
$(function () {
$('[data-toggle="popover"]').popover();
$('[data-toggle="tooltip"]').tooltip();
{# 定义局部变量parent_id#}
var parent_id = "";
{# 为提交事件绑定单击事件#}
$(".comment_btn").click(function () {
var $content = $("#tbCommentBody");
var article_id = "";
{# var parent_id = "";#}
var content = "";
var csrfmiddlewaretoken = $("input[name='csrfmiddlewaretoken']").val();
if (!$content.val()) {
alert("评论内容不能为空");
return false;
}
if (parent_id) {
var index = $content.val().indexOf("\n");
content = $content.val().slice(index + 1);
} else {
content = $content.val();
}
$.ajax({
url: '/blog/comment/',
type: 'post',
data: {
article_id: article_id,
parent_id: parent_id,
content: content,
csrfmiddlewaretoken: csrfmiddlewaretoken
},
success: function (data) {
console.log(data);
if (data.state) {
uname = "";
comment_new_html = `
<li class="comment-item list-group-item">
<div class="comment-title">${uname}</div>
<span class="pull-right comment-reply">
<a href="">刷新页面</a></span><div class="comment-body">sdsdfsdsdf</div></li>
`;
$commentlist = $(".comment-list");
$commentlist.append(comment_new_html);
$content.val("");
parent_id = "";
} else {
console.log('失败')
}
}
})
});
{# 为回复链接绑定事件#}
$(".comment-reply").click(function () {
var $content = $("#tbCommentBody");
$content.focus();
var val = $(this).attr("username");
$content.val("@" + val + "\n");
parent_id = $(this).attr("pk");
});
});
评论树
(function () {
$.ajax({
url: '/blog/comment-list/' + $("#info").attr("article_id"),
success: function (com_list) {
$.each(com_list, function (key, value) {
var pid = value.parent_comment_id;
var id = value.id;
var content = value.content;
var uname = value.user__username;
floor = document.createElement("div");
$floor = $(floor);
$floor.attr("class", "comment_item_tree");
$floor.attr("id", id);
$floor.text(id + "---" + content);
comment_new_html = `
<div class="comment_item_tree well" id="${id}">
<span class="comment-title">${uname}</span>
<span class="comment-body">${content}</span>
</div>
`;
// console.log(floor);
// console.log(comment_new_html);
// 如果父评论存在,找到父评论
if (pid) {
// $("#" + pid).append($floor);
console.log('pid',$("#" + pid));
$("#" + pid).append(comment_new_html);
} else {
// $(".comment_tree").append($floor);
$(".comment_tree").append(comment_new_html);
}
})
}
});
})();
视图viesw
评论列表
def comment(request):
"""
评论
:param request:
:return:
"""
print(request.POST)
ret = {'state':False}
article_id = request.POST.get('article_id')
pid = request.POST.get('parent_id')
content = request.POST.get('content')
uid = request.user.pk
try:
with transaction.atomic():
if pid:
models.Comment.objects.create(article_id=article_id,content=content,user_id=uid,parent_comment_id=pid)
else:
models.Comment.objects.create(article_id=article_id,content=content,user_id=uid)
models.Article.objects.filter(pk=article_id).update(comment_count=F("comment_count")+1)
ret['state'] = True
except Exception as e:
print(e)
return JsonResponse(ret)
评论树
def comment_list(request,article_id):
"""
获取当前文章的评论
:param request:
:param article_id:
:return:
"""
com_list = list(models.Comment.objects.filter(article_id=article_id).values("id",
"parent_comment_id",
"content",
"user__username"))
print(com_list)
return JsonResponse(com_list,safe=False)