需求分析

一般论坛中有评论和子评论,这样很容易就成了一个评论树,比如以下情况,先看数据结构:

#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 %}

版权声明:本文为ccorz原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/ccorz/p/5985534.html