需求分析
一般論壇中有評論和子評論,這樣很容易就成了一個評論樹,比如以下情況,先看數據結構:
#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 %}
