Blog Systerm--多級評論的樹形結構實現方式


由於做博客園系統的時候發現評論功能的實現耗費蠻長時間,比較適合練習,遂整理如下:

評論分為:對文章的評論和對評論的評論。

有兩種方式實現多級評論,一種類似博客園特色的評論方式,蓋樓@某位用戶。一種采用樹形結構實現,涉及一個很重要的點:字典和列表是引用數據類型,或者說可變類型;字典的鍵必須是不可變類型(可以是整型)。

主要整理第二種,學習數據結構的設計思想:

評論結構:

數字代表評論的ID號,由一張專門的comment表存放。

1,2,3,9為根級評論,代表對文章的評論,其余為子評論,代表對父級評論的評論。

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

主要代碼截取:
#############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))

##################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模塊     --針對標簽進行匹配查詢

第六點:文章一載入即顯示樹形評論

##############遞歸函數##############

{#                遞歸函數#}
        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;
        }

 

################樣式設置:多級評論顯示出層級效果的關鍵一步:

$(".comment_item").css({"marginLeft": "40px", "marginBottom": "10px"});

 

tips1:無序字典變有序字典

from collections import OrderDict
import collections
comment_dict=collections.OrderDict()

 tips2:常用

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  用戶在跳轉的登陸界面中完成登陸后,自動訪問跳轉到之前訪問的地址)

后續補充。


免責聲明!

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



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