django中的多級評論


需求分析

一般論壇中有評論和子評論,這樣很容易就成了一個評論樹,比如以下情況,先看數據結構:

#nid,評論內容,跟帖對象(None為根評論)
(1, '111', None),
(2, '222', None),
(3, '33', None),
(9, '999', 5),
(4, '444', 2),
(5, '555', 1),
(6, '666', 4),
(7, '777', 2),
(8, '888', 4),

可以使用遞歸來處理,先把數據通過有序字典,key為對象,value為有序字典,依次類推!

代碼部分

views.py:

from django.shortcuts import render
import collections
# Create your views here.

def tree_search(d_dic, comment_obj):
    # 在comment_dic中一個一個的尋找其回復的評論
    # 檢查當前評論的 reply_id 和 comment_dic中已有評論的nid是否相同,
    # 如果相同,表示就是回復的此信息
    #   如果不同,則需要去 comment_dic 的所有子元素中尋找,一直找,如果一系列中未找,則繼續向下找
    for k, v_dic in d_dic.items():
        # 找回復的評論,將自己添加到其對應的字典中,例如: {評論一: {回復一:{},回復二:{}}}
        if k[0] == comment_obj[2]:
            d_dic[k][comment_obj] = collections.OrderedDict()
            return
        else:
            # 在當前第一個跟元素中遞歸的去尋找父親
            tree_search(d_dic[k], comment_obj)


def build_tree(comment_list):
    comment_dic = collections.OrderedDict()

    for comment_obj in comment_list:
        if comment_obj[2] is None:
            # 如果是根評論,添加到comment_dic[評論對象] = {}
            comment_dic[comment_obj] = collections.OrderedDict()
        else:
            # 如果是回復的評論,則需要在 comment_dic 中找到其回復的評論
            tree_search(comment_dic, comment_obj)
    return comment_dic


comment_list = [
    (1, '111', None),
    (2, '222', None),
    (3, '33', None),
    (9, '999', 5),
    (4, '444', 2),
    (5, '555', 1),
    (6, '666', 4),
    (7, '777', 2),
    (8, '888', 4),
]


def comment(request):
    comment_dict = build_tree(comment_list)

    return render(request, 'comment.html', {'comment_dict': comment_dict})
    

model.py

from django.db import models

# Create your models here.

class SendMsg(models.Model):

    nid = models.AutoField(primary_key=True)
    code = models.CharField(max_length=6)
    email = models.CharField(max_length=32, db_index=True)
    times = models.IntegerField(default=0)
    ctime = models.DateTimeField()


class UserInfo(models.Model):
    nid = models.AutoField(primary_key=True)
    username = models.CharField(max_length=32, unique=True)
    password = models.CharField(max_length=32)
    email = models.CharField(max_length=32, unique=True)
    ctime = models.DateTimeField()

class NewsType(models.Model):
    nid = models.AutoField(primary_key=True)

    caption = models.CharField(max_length=32)


class News(models.Model):
    nid = models.AutoField(primary_key=True)
    user_info = models.ForeignKey('UserInfo')
    news_type = models.ForeignKey('NewsType')
    title = models.CharField(max_length=32, db_index=True)
    url = models.CharField(max_length=128)
    content = models.CharField(max_length=50)
    favor_count = models.IntegerField(default=0)
    comment_count = models.IntegerField(default=0)
    ctime = models.DateTimeField()


class Favor(models.Model):


    nid = models.AutoField(primary_key=True)

    user_info = models.ForeignKey('UserInfo')
    news = models.ForeignKey('News')

    ctime = models.DateTimeField()

    class Meta:
        unique_together = (("user_info", "news"),)


class Comment(models.Model):
    nid = models.AutoField(primary_key=True)

    user_info = models.ForeignKey('UserInfo')
    news = models.ForeignKey('News')

    up = models.IntegerField(default=0)
    down = models.IntegerField(default=0)
    ctime = models.DateTimeField()


    device = models.CharField(max_length=16)
    content = models.CharField(max_length=150)

    reply_id = models.ForeignKey('Comment', related_name='b', null=True, blank=True)

自定義擴展simple_tag函數

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from django import template
from django.utils.safestring import mark_safe

register = template.Library()

TEMP1 = """
<div class='content' style='margin-left:%s;'>
    <span>%s</span>
"""


def generate_comment_html(sub_comment_dic, margin_left_val):
    html = '<div class="comment">'
    #遍歷子元素
    for k, v_dic in sub_comment_dic.items():
        html += TEMP1 % (margin_left_val, k[1])
        #假如子元素的值為真,說明有子評論
        if v_dic:
            #遞歸處理,直到全部處理完
            html += generate_comment_html(v_dic, margin_left_val)
        html += "</div>"
    html += "</div>"
    return html


@register.simple_tag
def tree(comment_dic):
    html = '<div class="comment">'
    for k, v in comment_dic.items():
        html += TEMP1 % (0, k[1])
        #設置向右偏移30個像素
        html += generate_comment_html(v, 30)
        html += "</div>"
    html += '</div>'

    return mark_safe(html)

comment.html

{% load xx %}

{% tree comment_dict %}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM