首页 > 其他分享 >Django评论树的实现

Django评论树的实现

时间:2023-05-05 17:35:03浏览次数:43  
标签:comment parent 实现 list Django content 评论 user id

Django评论树的实现

实现django评论树使用了三种方式

第一种方式通过递归实现

缺点:每次查找parent_id的时候都要在ret所有的元素里面找一遍,找不到再在元素的children中寻找,一直找到为止

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': '李四', 'parent_id': 6},
]
#评论列表的生成
#第一种方式基本递归,缺点每次查找都需要在ret所有的元素都找一遍,找不到在从儿子里面找一遍
#在在不到在在孙子里面找一遍,知道找到为止。重复寻找。
class Node:
    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': '李四', 'parent_id': 6},
    ]
    #递归
    def digui(ret,row):
        for rt in ret:
            if rt['id'] == row['parent_id']:
                row['children'] =[]
                rt['children'].append(row)
                return
                #ret= [
                #     {'id': 1, 'content': 'Python最牛逼', 'user': '小李', 'parent_id': None,'children';[
                #                             {'id': 4, 'content': '你最牛逼', 'user': '大王', 'parent_id': 1},
                #                             {'id': 5, 'content': '我最牛逼', 'user': '张三', 'parent_id': 1},
                #     ]},
                #     {'id': 2, 'content': 'Java最牛逼', 'user': '小李', 'parent_id': None,'children';[]},
                #     {'id': 3, 'content': 'PHP最牛逼', 'user': '小李', 'parent_id': None,'children';[]},
                # ]
            # {'id': 6, 'content': '你最牛逼', 'user': '李四', 'parent_id': 4},
            else:
                Node.digui(rt['children'],row)
    # @property
    def create_tree(self,comment_list):
        ret = []
        for row in comment_list:
            if not row['parent_id']: # None
                row['children'] = []
                ret.append(row)
                # [
                #     {'id': 1, 'content': 'Python最牛逼', 'user': '小李', 'parent_id': None,'children';[]},
                #     {'id': 2, 'content': 'Java最牛逼', 'user': '小李', 'parent_id': None,'children';[]},
                #     {'id': 3, 'content': 'PHP最牛逼', 'user': '小李', 'parent_id': None,'children';[]},
                # ]
            else:#是回复的某个评论
                #for i in ret:
                    # if row['parent_id'] == i['id']:
                    #     i['children'].append(row)  #二级评论实现
                    # else:
                    #     找三层
                    Node.digui(ret,row)

        return ret

#第一种执行
# print(Node().create_tree(comment_list))


第二种方式通过列表和字典的引用方式查找

缺点是查找的复杂度没有第一种多,但是每次找parent_id还是需要comment_list中全部找一遍,并且还有在comment_list中添加元素,在ret中引用第一层的元素会增加内存的消耗。

#第二种查找方式,字典列表的引用方式
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': '李四', 'parent_id': 6},
]
ret = []
for row in comment_list:
    row.update({'children':[]})

for item in comment_list:
    current_row = item
    current_row_parent_id = current_row['parent_id']
    if not current_row_parent_id:
        ret.append(item)
    else:
        for r in comment_list:
            if r['id'] == current_row_parent_id:
                r['children'].append(item) #把有parent_id的数据加入到comment_list对应ID的chilren列表中
                                            #而不是加入到rent中,因为是引用型ret中指向的内存地址是一致的

#缺点,当有不为空的parent_id的元素时,需要找comment_list中找一遍和parent_id相等的ID值,效率比递归的comment_list自身
#和子元素都找一遍的效率高,还有在comment_list中添加元素,在ret中引用第一层的元素会增加内存的消耗。
# print(ret)
# print(comment_list)


第三种方式基于hash查找

基于字典的查找方式

#第三种基于哈希查找,字典存储时会调用Python内部散列函数,将键(Key)作为参数进行转换,得到一个唯一的一个地址,然后将值
#存入这个地址中,所字典的查找也是基于哈希的,所以查找很快速
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': '李四', 'parent_id': 6},
]
#创建字典
ret = []
comment_list_dict = {}
for row in comment_list:
    row.update({'children':[]})
    comment_list_dict[row['id']] = row
print(comment_list_dict)
for item in comment_list:
    parent_row = comment_list_dict.get(item['parent_id'])
    if not parent_row:
        ret.append(item)
    else:
       parent_row['children'].append(item)
print(ret)


回归前端,使用simple_tag

返回的数据为一个处理好的字典,回归给前端的时候使用自定义模板标签,在Html中调用直接使用模板方法使用

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_list):
    html = '<div class="comment-list">'
    for v in comment_list:
        a = '<div class="comment-box"><span>'
        a += v['content'] + "</span>"
        a += diGui(v['children'])
        a += "</div>"
        html += a

    return mark_safe(html)

"""
 function diGui(children_list){
                var html = "";
                $.each(children_list,function (ck,cv) {
                       var b = '<div class="comment-box"><span>';
                       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.after(html);
        }
    """


{% load laogao %}
{% create_tree comment_tree %}
<style>
        .comment-box{
            margin-left: 20px;
        }
</style>

HTML

标签:comment,parent,实现,list,Django,content,评论,user,id
From: https://www.cnblogs.com/mengdie1978/p/17374818.html

相关文章

  • 企业vsftp搭建,通过虚拟用户配置实现权限个性化设置需求
    1,安装必要的软件包yuminstall-yvsftpdlibdb-utils2,设置虚拟账号信息(使用文件存储)2.1创建明文账户信息#vim/etc/vsftpd/vuser_listlinghu123456peng1234562.2创建数据库账户信息db_load-T-thash-f/etc/vsftpd/vuser_list/etc/vsftpd/vuser_list.db3,设置基于虚拟用......
  • Python实现遍历读取文件或文件夹
    参考:https://www.jb51.net/article/258341.htmos.walk本身已经是遍历读取,包含所有的子文件(夹)path=u'.'#文件路径defnewWalkFile2(file):#main_dir当前路径,sub_dir_list当前路径下的子文件夹是个数组,sub_file_list当前路径下具体文件formain_dir,sub_dir_l......
  • 使用require.context实现优雅的预加载
    前言在前端开发中,对页面花里胡哨度[注1]要求越高的页面,用到的图片、音频什么的就越多,比如什么结婚请柬、展会请柬、发布会宣传页、数据大屏。虽然现在浏览器不允许网页在没有用户交互的情况下播放音频,但是,我们依旧要在页面展现的同时,准备好所有的静态资源。注1:花里胡哨度(garish......
  • Django--数据及字段的增删改查
    字段的增删改查#增pwd=models.IntegerField(verbose_name="密码",null=True)#verbose_name说明;null可以为空is_delete=models.CharField(default=0)#设置为默认值#改直接改代码然后执行数据库迁移命令即可#删注释掉代码然后执行数据库迁移命令即可数据的......
  • 实现财富自由的初步规划方案
    先贴一张chatgpt给我的答案:下面的具体的可执行计划:1、提高工作岗位的技能掌握大前端技术栈,掌握iOS和前端技能2、寻找高薪工作学习人工智能的相关知识,并输出文章,争取早日转行到AI行业3、投资技能学习学习相关知识,并逐步实践4、副业每月落地一个新项目5、控制开支与储......
  • 基于ArkUI框架开发——图片模糊处理的实现
     原文:https://mp.weixin.qq.com/s/vwXVj5vmAxDRG_jTk_8hPA,点击链接查看更多技术内容。现在市面上有很多APP,都或多或少对图片有模糊上的设计,所以,图片模糊效果到底怎么实现的呢?首先,我们来了解下模糊效果的对比 从视觉上,两张图片,有一张是模糊的,那么,在实现图片模糊效果之前,......
  • C# Pdf转图片通过(PdfiumViewer或O2S.Components.PDFRender4NET)实现
    1、通过PdfiumViewer实现,目前测试结果来看是不收费的,可直接通过Nuget添加引用///<summary>///pdf转图片///</summary>///<paramname="pdfPath">pdf路径</param>///<paramname="imagePath">输出图片路径&l......
  • 【Vue】vue3 vue-pdf-embed 实现pdf预览、缩放、拖拽、旋转和左侧菜单选择
    实际效果安装插件pnpminstallvue-pdf-embedpnpminstallvue3-pdfjs左侧pdf菜单组件<template><divclass="pdf-view-list"><divclass="itemactive-item"v-for="(item,index)inpageTotalNum"@click="itemClcik(i......
  • C# 通过iTextSharp实现关键字签字盖章(通过在内容中插入盖章图片的形式)
    此功能通过 iTextSharp 读取PDF文档信息,并循环查找每一页PDF文件,在整个PDF中只要是符合条件的地方都会盖章,如只需要在最后一页盖章,请将方法中For循环去掉,并将PdfContentBytecontentByte=pdfStamper.GetUnderContent(i);parser.ProcessContent<PdfLocation>(i,location);......
  • C# 通过ICSharpCode.SharpZipLib实现文件压缩下载
    通过管理NuGet包添加ICSharpCode.SharpZipLib引用以完成,多文件或者文件夹压缩后下载效果1、压缩文件实体类///<summary>///文件路径集合,文件名集合,压缩文件名///</summary>publicclassFileNameListZip{///<summary>///文件路......