简述:使用python字典的特性:可变数据类型,将数据库中的数据查询出来,将之转换成为一个字典,然后构建出有数据层级的一个列表,返回给前端。前端通过递归函数(自己调用自己)的方式将数据取出,在前端渲染出来,形成评论树的样式。
1.设计数据库: 评论表中利用评论的特点(利用父评论没有外键的关系,而子评论有外键父评论)有无父评论来区别该条评论是子评论还是父评论。
class Comment(models.Model):
"""
评论表
"""
nid = models.AutoField(primary_key=True)
article = models.ForeignKey(verbose_name='评论文章', to='Article', to_field='nid')
user = models.ForeignKey(verbose_name='评论者', to='UserInfo', to_field='nid')
content = models.CharField(verbose_name='评论内容', max_length=255)
create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
# 父评论字段,
parent_comment = models.ForeignKey('self', null=True)
def __str__(self):
return self.content
2,视图, 过滤出某个文章所有的评论, 然后将这个查询集通过字典的方式构建一个评论树的数据结构。
分析:
############ 分析 ##############################
# 获取详细文章的文章对象
#article_obj=Article.objects.get(nid=id)
# 获取与该篇文章相关的所有评论对象
#comment_list=Comment.objects.filter(article__nid=id)
# 获取评论树
# comment_list=Comment.objects.filter(article__nid=id).values("nid","content","parent_comment_id")
# print(comment_list)
# comment_dict = {}
#
# for comment in comment_list:
# comment["childern_list"] = []
# comment_dict[comment["nid"]] = comment
#
# result = []
# for key, comment in comment_dict.items():
# pid = comment["parent_comment_id"]
# if pid: # 子评论:comment
# comment_dict[pid].get("childern_list").append(comment) # 哈希查询 comment的父comment: comment_dict[pid]
# else:
# result.append(comment)
# 递归展开
获取并构建数据的视图
def get_comment_tree(request,id):
comment_list=Comment.objects.filter(article__nid=id).values("nid","content","parent_comment_id")
print(comment_list)
comment_dict = {}
for comment in comment_list:
comment["children_list"] = []
comment_dict[comment["nid"]] = comment
result = []
for key, comment in comment_dict.items():
pid = comment["parent_comment_id"]
if pid: # 子评论:comment
comment_dict[pid].get("children_list").append(comment) # 哈希查询 comment的父comment: comment_dict[pid]
else:
result.append(comment)
return JsonResponse(result,safe=False)
- 前端通过ajax 构建前端样式。
// 获取评论树:
var article_id=$(".info").attr("article_id");
$.ajax({
url:"/blog/get_comment_tree/"+article_id,
success:function (data) {
console.log(data);
var htmls=show_tree(data);
$(".comment_list_tree").append(htmls)
}
});
// 展开评论树
function show_tree(comment_list) { // [{"nid":67,"content":"111","children_list":[]},{},{}]
var html="";
$.each(comment_list,function (i,comment_dict) {
s='<div class="comment"><div class="content"><span>'+comment_dict["content"]+'</span></div>';
if (comment_dict["children_list"].length>0){ // [{},{}]
// 添加子评论样式
var temp=show_tree(comment_dict["children_list"]); // [{"nid":"","content":444,chilren:[]},]
s+=temp; // <div class="comment"><div class="content"><span>444</span></div></div>
console.log(temp); // <div class="comment"><div class="content"><span>444</span></div></div>
}
s+="</div>";
html+=s
});
return html
}
/*
*
*
*
*
s='<div class="comment"><div class="content"><span>'+comment_dict["content"]+'</span></div><div class="comment"><div class="content"><span>444</span></div></div>'
* html='<div class="comment"><div class="content"><span>'+111+'</span></div></div>
* <div class="comment"><div class="content"><span>222</span></div><div class="comment"><div class="content"><span>444</span></div></div>
* */
- 最后给每个div盒子加上一个maring-left , 评论树的样子就出来了。