• 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 %}
    
  • 相关阅读:
    Django-中间件
    Django-cookie与session
    Django-用户认证组件
    Django-forms组件
    Django-forms校验
    Django-ajax上传文件(request数据都可以在,request.body中找到)
    Django-Ajax传递json数据
    form表单文件上传
    Django-ROM(字段,参数)
    Django-模板的继承(母版,include)
  • 原文地址:https://www.cnblogs.com/ccorz/p/5985534.html
Copyright © 2020-2023  润新知