创建项目 django_comment 和应用 app01

修改 urls.py 文件

from django.contrib import admin
from django.urls import path
from app01 import views urlpatterns = [
path('admin/', admin.site.urls),
path('comment/', views.comment),
]

修改 views.py 文件

from django.shortcuts import render, HttpResponse
from app01 import models
# Create your views here. class Node: @staticmethod
def digui(ret, row):
for rt in ret: # 循环列表 ret
if rt['id'] == row['parent_id']: # 如果 rt 记录中的 id 与 row 的 praent_id 一样,则执行以下操作
row['children'] = []
rt['children'].append(row) # 在 rt key 为 children 的值中添加 row 记录
return
else:
Node.digui(rt['children'], row) # 递归执行,判断 children 值里面的 id 是否与 row 的 praent_id 一样 @staticmethod
def create_tree(comment_list):
ret = [] # 定义列表 ret
for row in comment_list: # 循环列表
if not row['parent_id']: # 如果记录中 parent_id 不会空就执行操作
row['children'] = []
ret.append(row)
else:
Node.digui(ret, row) # 如果记录中 parent_id 为空就执行操作
return ret def comment(request):
comment_list = [
{'id': 1, 'content': 'Python is best', 'user': 'klvchen', 'parent_id': None},
{'id': 2, 'content': 'Java is best', 'user': 'klvchen', 'parent_id': None},
{'id': 3, 'content': 'PHP is best', 'user': 'klvchen', 'parent_id': None},
{'id': 4, 'content': 'what is best', 'user': 'lily', 'parent_id': 1},
{'id': 5, 'content': 'hahaha', 'user': 'lucy', 'parent_id': 1},
{'id': 6, 'content': 'Today', 'user': 'james', 'parent_id': 4},
{'id': 7, 'content': 'good', 'user': 'jack', 'parent_id': 2},
{'id': 8, 'content': 'I do not know', 'user': 'jack', 'parent_id': 3},
{'id': 9, 'content': 'en', 'user': 'klvchen', 'parent_id': 8},
{'id': 10, 'content': 'Hey Python', 'user': 'kim', 'parent_id': None},
] comment_tree = Node.create_tree(comment_list)
for i in comment_tree:
print(i) return HttpResponse('Comment')

访问 http://127.0.0.1:8000/comment/, 得到结果:

{'parent_id': None, 'user': 'klvchen', 'content': 'Python is best', 'children': [{'parent_id': 1, 'user': 'lily', 'content': 'what is best', 'children': [{'parent_id': 4, 'user': 'ja
mes', 'content': 'Today', 'children': [], 'id': 6}], 'id': 4}, {'parent_id': 1, 'user': 'lucy', 'content': 'hahaha', 'children': [], 'id': 5}], 'id': 1}
{'parent_id': None, 'user': 'klvchen', 'content': 'Java is best', 'children': [{'parent_id': 2, 'user': 'jack', 'content': 'good', 'children': [], 'id': 7}], 'id': 2}
{'parent_id': None, 'user': 'klvchen', 'content': 'PHP is best', 'children': [{'parent_id': 3, 'user': 'jack', 'content': 'I do not know', 'children': [{'parent_id': 8, 'user': 'klvc
hen', 'content': 'en', 'children': [], 'id': 9}], 'id': 8}], 'id': 3}
{'parent_id': None, 'user': 'kim', 'content': 'Hey Python', 'children': [], 'id': 10}

采用方式二:

Python 中字典,列表是引用类型。

新建一个 test.py 文件

comment_list = [
{'id': 1, 'content': 'Python is best', 'user': 'klvchen', 'parent_id': None},
{'id': 2, 'content': 'Java is best', 'user': 'klvchen', 'parent_id': None},
{'id': 3, 'content': 'PHP is best', 'user': 'klvchen', 'parent_id': None},
{'id': 4, 'content': 'what is best', 'user': 'lily', 'parent_id': 1},
{'id': 5, 'content': 'hahaha', 'user': 'lucy', 'parent_id': 1},
{'id': 6, 'content': 'Today', 'user': 'james', 'parent_id': 4},
{'id': 7, 'content': 'good', 'user': 'jack', 'parent_id': 2},
{'id': 8, 'content': 'I do not know', 'user': 'jack', 'parent_id': 3},
{'id': 9, 'content': 'en', 'user': 'klvchen', 'parent_id': 8},
{'id': 10, 'content': 'Hey Python', 'user': 'kim', 'parent_id': None},
] for row in comment_list:
row.update({'children': []}) # 为每条记录添加一个 children 的 key ret = [] # 定义一个 ret 列表
for item in comment_list:
current_row = item
current_row_parent_id = current_row['parent_id']
if not current_row_parent_id: # 记录不存在 parent_id 才执行
ret.append(item) # ret 列表添加记录
else:
for r in comment_list: # 遍历 comment_list
if r['id'] == current_row_parent_id: # 若记录 r 中的 id 与上面的 current_row['parent_id'] 相同
r['children'].append(item) # 把当前记录加入 r['children'] 中 print(ret)

运行结果

[{'content': 'Python is best', 'parent_id': None, 'children': [{'content': 'what is best', 'parent_id': 1, 'children': [{'content': 'Today', 'parent_id': 4, 'children': [], 'id': 6, 'user': 'james'}], 'id': 4, 'user': 'lily'}, {'content': 'hahaha', 'parent_id': 1, 'children': [], 'id': 5, 'user': 'lucy'}], 'id': 1, 'user': 'klvchen'}, {'content': 'Java is best', 'parent_id': None, 'children': [{'content': 'good', 'parent_id': 2, 'children': [], 'id': 7, 'user': 'jack'}], 'id': 2, 'user': 'klvchen'}, {'content': 'PHP is best', 'parent_id': None, 'children': [{'content': 'I do not know', 'parent_id': 3, 'children': [{'content': 'en', 'parent_id': 8, 'children': [], 'id': 9, 'user': 'klvchen'}], 'id': 8, 'user': 'jack'}], 'id': 3, 'user': 'klvchen'}, {'content': 'Hey Python', 'parent_id': None, 'children': [], 'id': 10, 'user': 'kim'}]

采用方式三:

通过字典来优化代码。因为字典是通过键来索引的,关联到相对的值,理论上他的查询复杂度是O(1)。

comment_list = [
{'id': 1, 'content': 'Python is best', 'user': 'klvchen', 'parent_id': None},
{'id': 2, 'content': 'Java is best', 'user': 'klvchen', 'parent_id': None},
{'id': 3, 'content': 'PHP is best', 'user': 'klvchen', 'parent_id': None},
{'id': 4, 'content': 'what is best', 'user': 'lily', 'parent_id': 1},
{'id': 5, 'content': 'hahaha', 'user': 'lucy', 'parent_id': 1},
{'id': 6, 'content': 'Today', 'user': 'james', 'parent_id': 4},
{'id': 7, 'content': 'good', 'user': 'jack', 'parent_id': 2},
{'id': 8, 'content': 'I do not know', 'user': 'jack', 'parent_id': 3},
{'id': 9, 'content': 'en', 'user': 'klvchen', 'parent_id': 8},
{'id': 10, 'content': 'Hey Python', 'user': 'kim', 'parent_id': None},
]
ret = []
comment_list_dict = {} for row in comment_list: # 遍历 comment_list
row.update({'children': []}) # 每条记录添加一个 children key
comment_list_dict[row['id']] = row # 创建 comment_list_dict 字典,row['id'] 为 key,vaule 是 row for item in comment_list:
parent_row = comment_list_dict.get(item['parent_id']) # 通过 item['parent_id'] 的获取其父亲记录
if not parent_row: # 若没有 parent_id
ret.append(item) # 在 ret 中增加记录
else:
parent_row['children'].append(item) # 其父亲记录的 children 添加当期记录 print(ret)

运行结果

[{'user': 'klvchen', 'parent_id': None, 'id': 1, 'content': 'Python is best', 'children': [{'user': 'lily', 'parent_id': 1, 'id': 4, 'content': 'what is best', 'children': [{'user': 'james', 'parent_id': 4, 'id': 6, 'content': 'Today', 'children': []}]}, {'user': 'lucy', 'parent_id': 1, 'id': 5, 'content': 'hahaha', 'children': []}]}, {'user': 'klvchen', 'parent_id': None, 'id': 2, 'content': 'Java is best', 'children': [{'user': 'jack', 'parent_id': 2, 'id': 7, 'content': 'good', 'children': []}]}, {'user': 'klvchen', 'parent_id': None, 'id': 3, 'content': 'PHP is best', 'children': [{'user': 'jack', 'parent_id': 3, 'id': 8, 'content': 'I do not know', 'children': [{'user': 'klvchen', 'parent_id': 8, 'id': 9, 'content': 'en', 'children': []}]}]}, {'user': 'kim', 'parent_id': None, 'id': 10, 'content': 'Hey Python', 'children': []}]

前端处理评论数据

增加 statics 文件夹,放入 jquery.min.js 文件

修改 settings.py

# 注释
# 'django.middleware.csrf.CsrfViewMiddleware', # 在最后添加
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "statics"),
]

修改 urls.py

# 添加
path('index/', views.index),

修改 views.py

from django.shortcuts import render, HttpResponse
from app01 import models
# Create your views here. def index(request):
return render(request, 'index.html') def comment(request):
news_id = request.GET.get('news_id') comment_list = [
{'id': 1, 'content': 'Python is best', 'user': 'klvchen', 'parent_id': None},
{'id': 2, 'content': 'Java is best', 'user': 'klvchen', 'parent_id': None},
{'id': 3, 'content': 'PHP is best', 'user': 'klvchen', 'parent_id': None},
{'id': 4, 'content': 'what is best', 'user': 'lily', 'parent_id': 1},
{'id': 5, 'content': 'hahaha', 'user': 'lucy', 'parent_id': 1},
{'id': 6, 'content': 'Today', 'user': 'james', 'parent_id': 4},
{'id': 7, 'content': 'good', 'user': 'jack', 'parent_id': 2},
{'id': 8, 'content': 'I do not know', 'user': 'jack', 'parent_id': 3},
{'id': 9, 'content': 'en', 'user': 'klvchen', 'parent_id': 8},
{'id': 10, 'content': 'Hey Python', 'user': 'kim', 'parent_id': None},
{'id': 10, 'content': 'I am god', 'user': 'god', 'parent_id': 6},
] comment_tree = []
comment_list_dict = {} for row in comment_list:
row.update({'children': []})
comment_list_dict[row['id']] = row for item in comment_list:
parent_row = comment_list_dict.get(item['parent_id'])
if not parent_row:
comment_tree.append(item)
else:
parent_row['children'].append(item) import json
return HttpResponse(json.dumps(comment_tree))

在templates 下添加 index.html

<!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="19" class="com">评论</a>
<div class="comment-box">
<span>Py最牛</span>
<div class="comment-box">
<span>PHP最牛</span>
<div class="comment-box">
<span>what a pity</span>
</div>
</div>
<div class="comment-box">
<span>en en en </span>
</div>
</div>
</div>
<div class="item">
<a news_id="18" class="com">评论</a>
</div>
<div class="item">
<a news_id="17" class="com">评论</a>
</div> <script src="/static/jquery.min.js"></script>
<script>
$(function () {
bindCommentEvent(); // 初始化 bindCommentEvent() 函数
}); function bindCommentEvent() {
$('.com').click(function () { // 添加点击事件
var news_id = $(this).attr('news_id'); // 获取 news_id
var _this = $(this); // 获取当前的元素 $.ajax({
url: '/comment/',
type: 'GET',
data: {news_id: news_id},
dataType: "JSON",
success:function (arg) {
create_tree(arg, _this); // 执行 create_tree() 函数
} })
})
} function diGui(children_list) {
var html = "";
$.each(children_list, function (ck, cv) { // 递归 children_list
var b = '<div class="comment-box"><span>'; // 拼凑 html 元素
b += cv.content + "</span>";
b += diGui(cv.children);
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 + "</span>";
// 创建自评论
a += diGui(v.children); // 递归所有子评论
a += "</div>";
html += a;
}); html += "</div>"
$this.append(html) } </script>
</body>
</html>

点击评论后,出现下面结果

后端处理评论数据

在 views.py 上添加

path('comment/', views.comment),

在 index.html 出修改

<!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="19" class="com">评论</a>
<div class="comment-box">
<span>Py最牛</span>
<div class="comment-box">
<span>PHP最牛</span>
<div class="comment-box">
<span>what a pity</span>
</div>
</div>
<div class="comment-box">
<span>en en en </span>
</div>
</div>
</div>
<div class="item">
<a news_id="18" class="com">评论</a>
</div>
<div class="item">
<a news_id="17" class="com">评论</a>
</div> <script src="/static/jquery.min.js"></script>
<script>
$(function () {
bindCommentEvent();
}); function bindCommentEvent() {
$('.com').click(function () {
var news_id = $(this).attr('news_id');
var _this = $(this); $.ajax({
url: '/comment/',
type: 'GET',
data: {news_id: news_id},
dataType: "html",
success:function (arg) {
_this.after(arg); // 在该元素后添加后台返回的数据
} })
})
}
</script>
</body>
</html>

创建一个 templateags 文件夹,里面创建 klvchen.py 文件

from django import template
from django.utils.safestring import mark_safe
register = template.Library() def diGui(children_list):
html = ""
for cv in children_list:
b = '<div class="comment-box"><span>'
b += cv['content'] + "</span>"
b += diGui(cv['children'])
b += "</div>"
html += b
return html @register.simple_tag
def create_tree(comment_tree):
html = '<div class="comment-list">'
for v in comment_tree:
a = '<div class="comment-box"><span>'
a += v['content'] + "</span>"
a += diGui(v['children'])
a += "</div>"
html += a return mark_safe(html)

在 templates 文件夹里,创建 comment.html 文件

{% load klvchen %}
{% create_tree comment_tree %}

修改 views.py 文件

from django.shortcuts import render, HttpResponse
from app01 import models
# Create your views here. def index(request):
return render(request, 'index.html') def comment(request):
news_id = request.GET.get('news_id') comment_list = [
{'id': 1, 'content': 'Python is best', 'user': 'klvchen', 'parent_id': None},
{'id': 2, 'content': 'Java is best', 'user': 'klvchen', 'parent_id': None},
{'id': 3, 'content': 'PHP is best', 'user': 'klvchen', 'parent_id': None},
{'id': 4, 'content': 'what is best', 'user': 'lily', 'parent_id': 1},
{'id': 5, 'content': 'hahaha', 'user': 'lucy', 'parent_id': 1},
{'id': 6, 'content': 'Today', 'user': 'james', 'parent_id': 4},
{'id': 7, 'content': 'good', 'user': 'jack', 'parent_id': 2},
{'id': 8, 'content': 'I do not know', 'user': 'jack', 'parent_id': 3},
{'id': 9, 'content': 'en', 'user': 'klvchen', 'parent_id': 8},
{'id': 10, 'content': 'Hey Python', 'user': 'kim', 'parent_id': None},
{'id': 10, 'content': 'I am god', 'user': 'god', 'parent_id': 6},
] comment_tree = []
comment_list_dict = {} for row in comment_list:
row.update({'children': []})
comment_list_dict[row['id']] = row for item in comment_list:
parent_row = comment_list_dict.get(item['parent_id'])
if not parent_row:
comment_tree.append(item)
else:
parent_row['children'].append(item) # import json
# return HttpResponse(json.dumps(comment_tree))
return render(request, 'comment.html', {'comment_tree': comment_tree})

运行结果

Django 简单评论实现的更多相关文章

  1. [个人网站搭建]·Django增加评论功能(Python3)

    [个人网站搭建]·Django增加评论功能 个人主页--> https://xiaosongshine.github.io/ 个人网站搭建github地址:https://github.com/ ...

  2. DJango简单的后台定义登录验证

    第一步创建一个新的项目 APPLICATIONNAME : 表示创建子项目 第二步:找到主项目的url 进行 include 分发式url 简单的说,就是将app里边的url放在这里. 这里也可以找到 ...

  3. 我的Vue之旅 07 Axios + Golang + Sqlite3 实现简单评论机制

    第三期 · 使用 Vue 3.1 + TailWind.CSS + Axios + Golang + Sqlite3 实现简单评论机制 效果图 CommentArea.vue 我们需要借助js的Dat ...

  4. Django——实现评论功能(包括评论回复)

    提示:(1)功能不全面,仅仅实现评论(2)样式简单 1.项目目录结构 2.模型 from django.db import models from django.contrib.auth.models ...

  5. Django简单的数据库操作

    当然,本篇的前提是你已经配置好了相关的环境,这里就不详细介绍. 一. 在settings.py文件中设置数据库属性. 如下: DATABASES = { 'default': { 'ENGINE': ...

  6. 循序渐进Python3(十二) --2--  web框架之django简单实现oracle数据库操作

    在 Django 中构建 Oracle 数据库支持的 Web 应用程序 了解如何配置 Django 以便与 Oracle 数据库交互,并使用 ORM 进行数据库连接.             产能在软 ...

  7. django 简单的邮件系统

    django邮件系统 Django发送邮件官方中文文档 总结如下: 1.首先这份文档看三两遍是不行的,很多东西再看一遍就通顺了. 2.send_mail().send_mass_mail()都是对Em ...

  8. Django多级评论

    一.原理 #多级评论原理简单原理,弄完之后发现基础白学了 msg_list = [ {'id':1,'content':'xxx','parent_id':None}, {'id':2,'conten ...

  9. 前端、数据库、Django简单的练习

    一.前端 1.前端页面由哪几层构成,分别是什么,作用是什么? 分为:结构层(html),表示层(css),行为层(js). 结构层 超文本标记语言.由HTML或XHTML之类的标记语言负责创建.标签, ...

随机推荐

  1. 第十章 Centos7-系统进程管理

    第十章  Centos7-系统进程管理 本节所讲内容: 10.1  进程概述和ps查看进程工具 10.2  uptime查看系统负载-top动态管理进程 10.3  前后台进程切换- nice进程优先 ...

  2. AtCoder - 2140 (思维)

    题意 https://vjudge.net/problem/AtCoder-2140 每次告诉你新的a:b,计算最后最小的a+b. 思路 如 3 2 3 1 1 3 2 先令a=2,b=3,发现新的为 ...

  3. show()和隐藏hide() slideDown()和 slideUp() fadeIn()和fadeOut()

    1==>显示show()和隐藏hide() 是一组动画 与切换toggle()$("div").show():当不传递参数时,没有动画效果,它将某个元素瞬间显示出来 $(&q ...

  4. Jquery调用ajax,出现一直跳转到error问题

    今天做项目的时候,遇到ajax请求,一直都是跳转到了error部分,一直没有进入success部分 后来查了一下网上的资料,有两三种说法, 一种是将dataType :'json',改成你相应的版本, ...

  5. luoguP3233 [HNOI2014]世界树

    题意 看见数据范围就知道是虚树,于是先建出虚树. 考虑先求出虚树上的点的管理点,显然两边dfs,一遍从下往上,一遍从上往下. 之后考虑不在虚树上的点,对于虚树上的每一条边\((u,v)\),我们考虑上 ...

  6. node爬虫之图片下载

    背景:针对一些想换头像的玩家,而又不知道用什么头像的,作为一名代码爱好者,能用程序解决的,就不用程序来换头像,说干就干,然后就整理了一下. 效果图 环境配置 安装node环境 node -v node ...

  7. 小测试整理(含T1 T2)

    这次测试规模较小,前两题也较水,但需要整理 T1(Jelly的男♂难题1): 从一个点出发,以四连通的方式扩散,可以走#,不能走o,走过的格子每单位时间会增加1点高度,问扩散完整间屋子需要的时间,以及 ...

  8. 深入理解Linux内核 学习笔记(8)

    第八章 系统调用 API定义了一个给定的服务:系统调用是通过软中断向内核发出一个明确的请求. API可能不调用系统调用,也可能调用多个系统调用. Linux系统调用必须通过执行int 0x80,系统调 ...

  9. telnet: Unable to connect to remote host: No route to host

    用iptables -F这个命令来关闭防火墙,但是使用这个命令前,千万记得用iptables -L查看一下你的系统中所有链的默认target,iptables -F这个命令只是清除所有规则,只不会真正 ...

  10. Docker安装使用以及mlsql的docker安装使用说明

    1.检查内核版本,必须是3.10及以上 uname -r 2.安装 yum -y install docker #1.启动   docker systemctl start docker #1.1.验 ...