• Django 简单评论实现


    创建项目 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})
    

    运行结果

  • 相关阅读:
    201521123076《java程序设计》第四次总结
    201521123076《java程序设计》第三周学习总结
    201521123076《Java程序设计》第2周学习总结
    软件工程网络15个人阅读作业2
    软件工程网络15个人作业1
    java程序设计----学生基本信息管理系统
    201521123070 《JAVA程序设计》第14周学习总结
    201521123070 《JAVA程序设计》第13周学习总结
    201521123070 《JAVA程序设计》第12周学习总结
    201521123070《Java程序设计》 第11周学习总结
  • 原文地址:https://www.cnblogs.com/klvchen/p/11351601.html
Copyright © 2020-2023  润新知