我们知道,在实现BBS项目时,评论的功能是必不可少的。
先配置好环境
(urls)
from django.contrib import admin
from django.urls import path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('comment/', views.comment),
path('index.html/', views.index),
]
(models)
class UserInfo(models.Model):
name = models.CharField(max_length=32)
class News(models.Model):
title = models.CharField(max_length=32)
class Comment(models.Model):
content = models.CharField(max_length=32)
news = models.ForeignKey('News',on_delete=models.CASCADE)
user_info = models.ForeignKey('UserInfo',on_delete=models.CASCADE)
parent = models.ForeignKey('self',related_name='o',null=True,on_delete=models.CASCADE)
ctime = models.DateTimeField(auto_now_add=True,null=True)
可以将数据库中的数据,以列表中包含字典的形式打印出来
#models.xxx.filter(news_id=news_id).values(...)
ppp = models.Comment.objects.all().values()
print(ppp)
为了方便,我们以数据库的形式手动创建一个列表,不再在数据库中一条条的插入,创建的评论列表如下:
comment_list = [
{'id': 1, 'content': 'Python最牛逼', 'user': '搞基建', 'parent_id': None},
{'id': 2, 'content': 'Java最牛逼', 'user': '搞基建', 'parent_id': None},
{'id': 3, 'content': 'PHP最牛逼', 'user': '搞基建', 'parent_id': None},
{'id': 4, 'content': '你最牛逼', 'user': '小比虎', 'parent_id': 1},
{'id': 5, 'content': '老师最你比', 'user': '李欢', 'parent_id': 1},
{'id': 6, 'content': '郭永昌是...', 'user': '郭永昌', 'parent_id': 4},
{'id': 7, 'content': '哈哈我是流氓...', 'user': '崔月圆', 'parent_id': 2},
{'id': 8, 'content': '我女朋友好漂亮...', 'user': '崔月圆', 'parent_id': 3},
{'id': 9, 'content': '见到你女友,交定你朋友...', 'user': '搞基建', 'parent_id': 8},
{'id': 10, 'content': '见到你女友,交定你朋友...', 'user': '鼻环', 'parent_id': None},
{'id': 11, 'content': '我是大胖...', 'user': 'xiaopang', 'parent_id': 6},
]
第一种方法:在后端利用递归实现评论数据结构:
#第一种方法,用递归实现评论数据结构
class Node(object):
@staticmethod
def Recursive(ret,row):
for cr in ret:
if row['parent_id'] == cr['id']:
row['childen'] = []
cr['childen'].append(row)
return
else:
Node.Recursive(cr['childen'],row)
@staticmethod #静态方法,函数中并没有封装东西,Node.create_tree即可调用
def create_tree(comment_list):
ret = []
for row in comment_list:
if row['parent_id'] == None:
row['childen'] = []
ret.append(row)
else:
#注释部分为思路,一层一层的创建下去,引申到递归
# for i in ret:
# if row['parent_id'] == i['id']:
# row['childen'] = []
# i['childen'].append(row)
# else:
# pass
Node.Recursive(ret,row)
return ret
def comment(request):
"""每条新闻下面有评论,然后评论之间可以互相评论,这让评论之间出现了层级的关系。
所以我们需要将列表重新组合一下,使得以及品论存储着二级评论
"""
comment_list = [
{'id': 1, 'content': 'Python最牛逼', 'user': '搞基建', 'parent_id': None},
{'id': 2, 'content': 'Java最牛逼', 'user': '搞基建', 'parent_id': None},
{'id': 3, 'content': 'PHP最牛逼', 'user': '搞基建', 'parent_id': None},
{'id': 4, 'content': '你最牛逼', 'user': '小比虎', 'parent_id': 1},
{'id': 5, 'content': '老师最你比', 'user': '李欢', 'parent_id': 1},
{'id': 6, 'content': '郭永昌是...', 'user': '郭永昌', 'parent_id': 4},
{'id': 7, 'content': '哈哈我是流氓...', 'user': '崔月圆', 'parent_id': 2},
{'id': 8, 'content': '我女朋友好漂亮...', 'user': '崔月圆', 'parent_id': 3},
{'id': 9, 'content': '见到你女友,交定你朋友...', 'user': '搞基建', 'parent_id': 8},
{'id': 10, 'content': '见到你女友,交定你朋友...', 'user': '鼻环', 'parent_id': None},
{'id': 11, 'content': '我是大胖...', 'user': 'xiaopang', 'parent_id': 6},
]
comment_tree = Node.create_tree(comment_list)
print(comment_tree)
print(ret)
import json
return HttpResponse(json.dumps(ret))
第二种方法:利用循环实现评论数据结构:
#第二种,用循环实现评论数据结构
ret = []
comment_list_dict = {}
# for i in comment_list:
# i.update({'childen':[]})
#
# for item in comment_list:
# if item['parent_id'] == None:
# ret.append(item)
# else:
# for i in comment_list:
# if i['id'] == item['parent_id']:
# i['childen'].append(item)
# print(ret)
#对第二种方法的改版
for i in comment_list:
i.update({'childen':[]})
comment_list_dict[i['id']] = i
for item in comment_list:
if item['parent_id'] == None:
ret.append(item)
else:
comment_list_dict[item['parent_id']]['childen'].append(item)
print(ret)
配置好views
def index(request):
return render(request,'index.html')
利用JS递归,在前端显示层级评论
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.comment-box{
margin-left: 20px;
}
</style>
</head>
<body>
<div class="item">
<a news_id = "1" class="com">评论</a>
</div>
<script src="/static/jquery-3.3.1.js"></script>
<script>
$(function () {
bindCommentEvent();
});
function Recursive(childen_list) {
var html = '';
$.each(childen_list,function (ck,cv) {
var b = '<div class="comment-box"><span>';
b += cv.content;
b += "</span>";
var result1 = cv.childen;
b += result1;
b+= "</div>";
html += b;
});
return html;
}
function create_tree(data,_this) {
var html = '<div class="comment-list">';
$.each(data,function (k,v) {
var a = '<div class="comment-box"><span>';
a += v.content;
a += "</span>";
{# //创建自评论,利用递归实现,这里创将第二层方便理解#}
var result1 = Recursive(v.childen);
{# $.each(v.childen,function (ck,cv) {#}
{# var b = '<div class="comment-box"><span>';#}
{# b += cv.content;#}
{# b += "</span>";#}
{# b+= "</div>";#}
{# a += b;#}
{# });#}
a += result1;
a += "</div>";
html += a;
});
html +="</div>";
_this.append(html)
}
function bindCommentEvent() {
$('.com').click(function () {
var news_id = $(this).attr('nes_id');
var _this = $(this);
$.ajax({
url:'/comment/',
type: 'GET',
data:{'news_id':news_id},
dataType:"JSON",
success:function (arg) {
{# console.log(arg);#}
create_tree(arg,_this);
}
})
})
}
</script>
</body>
</html>
效果预览: