Blog Systerm--多级评论的树形结构实现方式

由于做博客园系统的时候发现评论功能的实现耗费蛮长时间,比较适合练习,遂整理如下:

评论分为:对文章的评论和对评论的评论。

有两种方式实现多级评论,一种类似博客园特色的评论方式,盖楼@某位用户。一种采用树形结构实现,涉及一个很重要的点:字典和列表是引用数据类型,或者说可变类型;字典的键必须是不可变类型(可以是整型)。

主要整理第二种,学习数据结构的设计思想:

评论结构:

数字代表评论的ID号,由一张专门的comment表存放。

1,2,3,9为根级评论,代表对文章的评论,其余为子评论,代表对父级评论的评论。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Comment(models.Model):
    '''
    一篇文章可以有多个评论,一条评论只能属于一篇文章;
    一个用户可以有多条评论,一条评论只能属于一个用户;
    评论还可以有评论;
    还有一个字段存放用户评论时间;
    评论点赞次数;
     
    '''
    commentInfo=models.CharField(max_length= 200,verbose_name= "评论内容")
    article=models.ForeignKey("Article",verbose_name= "评论文章")
    user=models.ForeignKey("UserInfo",verbose_name= "评论人")
    parent_id=models.ForeignKey("self",verbose_name= "父级评论",null=True)  #做了修改
    create_time=models.DateTimeField(verbose_name= "评论时间",auto_now_add= True)
#     设置评论被赞的次数
    up_count=models.IntegerField(default= 0)
 
    def __str__(self):
        return self.commentInfo
 
#     通过评论找文章:(正向)article_obj=comment_obj.article
#     通过文章找评论:(反向)article_obj.comment_set.all
 
#     通过评论找到评论用户:(正向)comment_obj.user

 代码实现:

方式一:

方式二:

推荐方式二:尽量避免for循环嵌套for循环方式,优化性能。

评论功能实现要点记录:

 第一点:点击评论可以直接定位到评论输入框,技术实现:锚点或者前端的scrollIntoView()用法。

 第二点:评论区采用富文本编辑框Kindeditor。注意上传文件以及路径配置。详细参考官网文档:http://kindeditor.net/doc.php

1
主要代码截取:<br>#############views.py#############
def upload_file(request):
if request.method == "POST":
file_obj = request.FILES.get("imgFile")
print(file_obj, type(file_obj)) # 1.jpg <class 'django.core.files.uploadedfile.InMemoryUploadedFile'>
print(file_obj.name, type(file_obj.name)) # 1.jpg <class 'str'>
file_name = file_obj.name
file_path = os.path.join("blog/media/upload/img/", file_name) # blog/media/upload/img/1.jpg
print(file_path)
with open(file_path, "wb") as f:
for chunk in file_obj.chunks():
f.write(chunk)

response_put = {
"error": 0,
"url": "/media/upload/img/" + file_name, # 特别注意路径问题
}
return HttpResponse(json.dumps(response_put))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<br>##################templates之articledetail.html##################
<form>
            {% csrf_token %}
            <h5>评论:</h5>
            <div id="contentArea2">
                <textarea cols="60" rows="10" id="contentArea"> {# 试了,name不可以 #}
            </textarea>
            </div>
            <div>
                <input type="button" value="提交" class="CommentSub">
            </div>
</form>
 
{#    富文本编辑框设置#}
 
        Keditor = KindEditor.create("#contentArea", {
            width: "850px",
            resizeType: 1,
            uploadJson: "/upload_file/", {# 指定上传文件的服务器端程序。 #}
            extraFileUploadParams: {"csrfmiddlewaretoken": "{{ csrf_token }}"}, {# 上传图片、Flash、视音频、文件时,支持添加别的参数一并传到服务器。 #}
            filePostName: "imgFile"
        });

 非常有用的取值和赋值操作:

第三点:采用文本编辑框输入评论内容,用ajax方式提交评论时,要注意运用:$(document).ready(function(){})============>$(function(){})

第四点:处理新添评论时,前端有两种方式,一种字符串拼接,还有我们可以有效的借助别人写好的格式化字符串处理工具。

第五点:BeautifulSoup模块     --针对标签进行匹配查询

第六点:文章一载入即显示树形评论

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
##############递归函数##############
 
{#                递归函数#}
        function makeCommentTree(comment_list) {
            var htmls = '';
            $.each(comment_list, function (i, comment) {
                {#                console.log(i, comment);#}
                {#                var comment_str = '<div class="comment_item"><div class="content"><span>' + comment["id"] + '</span></div>';#}
                var comment_str = '<div class="comment_item"><div class="row">' +
                    '<div class="col-md-1"><a href="#"><img src="' + comment["comment_user_headPic"] + '" width="40px" height="40px" class="comment_user_headPic"></a></div>' +
                    '<div class="col-md-11"><span class="comment_time">' + comment["create_time"] + '</span>' +
                    '<a href="#" class="comment_user">' + comment["comment_user_username"] + '</a>' +
                    '<a href="#contentArea2" class="comment_comment pull-right">回复<span class="glyphicon glyphicon-comment"></span></a>' +
                    '<a href="#" class="pull-right">支持<span class="glyphicon glyphicon-thumbs-up"></span> </a>' +
                    '<div class="comment_info">' + comment["commentInfo"] + '</div><span class="' + comment["id"] + '"></span></div></div>';
                if (comment["children_comments"]) {
                    comment_str += makeCommentTree(comment["children_comments"]);
                }
                comment_str += '</div>';
                htmls += comment_str;
            });
 
            return htmls;
        }

 

1
2
3
################样式设置:多级评论显示出层级效果的关键一步:
 
$(".comment_item").css({"marginLeft": "40px", "marginBottom": "10px"});

 

tips1:无序字典变有序字典

1
2
3
from collections import OrderDict
import collections
comment_dict=collections.OrderDict()

 tips2:常用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
1、window.location.href(设置或获取整个 URL 为字符串)
 
var test = window.location.href;
alert(test);
返回:http://i.cnblogs.com/EditPosts.aspx?opt=1
 
 
2、window.location.protocol(设置或获取 URL 的协议部分)
 
var test = window.location.protocol;
alert(test);
返回:http:
 
3、window.location.host(设置或获取 URL 的主机部分)
 
var test = window.location.host;
alert(test);
返回:i.cnblogs.com
 
 
4、window.location.port(设置或获取与 URL 关联的端口号码)
 
var test = window.location.port;
alert(test);
返回:空字符(如果采用默认的80端口(update:即使添加了:80),那么返回值并不是默认的80而是空字符)
 
5、window.location.pathname(设置或获取与 URL 的路径部分(就是文件地址))
var test = window.location.pathname;
alert(test);
返回:/EditPosts.aspx
 
6、window.location.search(设置或获取 href 属性中跟在问号后面的部分)
 
var test = window.location.search;
alert(test);
返回:?opt=1
 
PS:获得查询(参数)部分,除了给动态语言赋值以外,我们同样可以给静态页面,并使用javascript来获得相信应的参数值。
 
7、window.location.hash(设置或获取 href 属性中在井号“#”后面的分段)
 
var test = window.location.hash;
alert(test);
返回:空字符(因为url中没有)
 
8、js获取url中的参数值

 暂时就这些。

当然博客系统还有很多未整理出来的,比如用户注册时上传头像的预览,涉及的FormData。验证码的刷新。对文章按日期归档时运用的自定义管理器。

request.path运用(

要求:

1  用户登陆后才能访问某些页面,

2  如果用户没有登录就访问该页面的话直接跳到登录页面

3  用户在跳转的登陆界面中完成登陆后,自动访问跳转到之前访问的地址)

后续补充。

posted @ 2018-03-07 21:32  dion至君  阅读(695)  评论(0)    收藏  举报