Django 簡單評論實現

創建項目 django_comment 和應用 app01

修改 urls.py 文件

如果你對python感興趣,我這有個學習Python基地,裏面有很多學習資料,感興趣的+Q羣:688244617

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})

運行結果
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章