摘要:在父頁面中文章詳情模板添加需要執(zhí)行錨點拼接的函數(shù)新增函數(shù),處理二級回復去除尾部符號刷新并定位到錨點函數(shù)中運用了的三元運算符,翻譯成人話就是如果成立則返回,如果不成立就返回。
老讀者注意:上一章消息通知有個bug,即發(fā)給管理員的notify必須移動到new_comment.save()的后面,否則會導致action_object存儲為NULL,并且導致本章的html拼接錨點失效。原文已更正,為博主的疏忽表示歉意。
上一章已經(jīng)實現(xiàn)了消息通知功能,可以很人性化的把用戶引導到被他人回復的頁面中去。
但是仔細想想,似乎還有不方便的地方:如果頁面中評論較多,想找到感興趣的那一條評論還是要費點功夫的。所以這個消息通知,最好是能夠不僅前往正確的頁面,還要前往正確的位置(需求是無窮無盡的..)。
為了實現(xiàn)這個功能,本章就要介紹一個非常古老的功能:錨點定位。以及如何在Django中實現(xiàn)它。
錨點是什么我們在寫html文件的容器時,經(jīng)常會用到id屬性:
apple
這個id屬性不僅可以作為Javascript或者css代碼查詢某個容器的標記,還可以作為錨點,定位頁面應該前往的位置。輸入下面的地址:
http://www.myblog.com/home#fruit
瀏覽器就會打開home頁面,并且視窗前往id="fruit"的容器。
明白了錨點是什么,下面就通過三種不同的實現(xiàn)方法,看看錨點在Django博客項目中是如何應用的。
三種實現(xiàn) html拼接錨點首先要實現(xiàn)的功能,就是當管理員點擊消息通知時,瀏覽器視窗前往此通知的評論位置。
因此首先修改文章詳情頁面,給渲染評論的div容器添加id屬性:
templates/article/detail.html ... {% recursetree comments %} {% with comment=node %}...{% endwith %} {% endrecursetree %} ...{{ children }}{% endif %}
我們還是用comment.id來給每條評論賦予唯一的id值。注意id屬性保持唯一性。前面在二級回復的Modal中用了comment_{{ comment.id }},這里千萬不要重復了。
然后修改通知列表模板,添加錨點:
templates/notice/list.html ... {% for notice in notices %}
注意這里url中拼接了兩種玩意兒:
跟在?后面的是查詢參數(shù),用于給視圖傳遞參數(shù),是之前寫的舊代碼
跟在#后面的是錨點,也就是本章正在學的東東
?和#一個重要的差別,就是?不能夠傳遞到下個頁面的url中去,而#可以。
測試一下,用普通用戶賬號發(fā)幾條一級評論,登錄管理員賬號并點擊消息通知:
瀏覽器視窗沒有在頁面頂部,而是直接前往到該條評論處。
通過html拼接是實現(xiàn)錨點最簡單直接的方法。
視圖拼接html拼接雖好,但它不是萬能的。如果要前往一個當前頁面還沒有創(chuàng)建的容器,該怎么辦?
舉個栗子。按照目前我們的博客設計,當用戶發(fā)表評論時,頁面會刷新、視窗將停留在文章詳情的頂部。但實際上這時候視窗應該停留在新發(fā)表的評論處才比較合理,因為用戶可能想檢查一下自己發(fā)表的評論是否正確。而在原頁面時由于新評論都還沒發(fā)表,所以comment.id是不存在的,沒辦法用html拼接錨點。讀者好好思考一下是不是這樣。
這種情況下就需要在視圖中拼接錨點了。修改文章評論視圖,將錨點拼接到redirect函數(shù)中:
comment/views.py ... # 文章評論視圖 def post_comment(request, article_id, parent_comment_id=None): ... # 已有代碼 if request.method == "POST": ... if comment_form.is_valid(): ... if parent_comment_id: ... new_comment.save() if not request.user.is_superuser: notify.send(...) # 新增代碼,添加錨點 redirect_url = article.get_absolute_url() + "#comment_elem_" + str(new_comment.id) # 修改redirect參數(shù) return redirect(redirect_url)
get_absolute_url()是之前章節(jié)寫的方法,用于查詢某篇文章的地址。
說白了就是把拼接的位置從模板挪到了視圖中,因為新評論必須在視圖中保存之后才會被分配一個id值。
流動的數(shù)據(jù)最后我們來看稍微復雜點的情況。
當用戶發(fā)表一級評論時,我們在視圖中拼接錨點解決了刷新當前頁面并定位的問題。但是二級評論是通過iframe + ajax實現(xiàn)的,這又該怎么辦?
理一理思路。
首先,新評論的id值是在視圖中創(chuàng)建的,但是由于視圖是從iframe中請求的,在視圖中沒辦法刷新iframe的父頁面。所以我們唯一能做的就是把數(shù)據(jù)傳遞出去,到前端去處理。
修改文章評論視圖:
comment/views.py # 引入JsonResponse from django.http import JsonResponse ... # 文章評論視圖 def post_comment(request, article_id, parent_comment_id=None): article = get_object_or_404(ArticlePost, id=article_id) # 已有代碼 if request.method == "POST": ... if comment_form.is_valid(): ... if parent_comment_id: ... # 修改此處代碼 # return HttpResponse("200 OK") return JsonResponse({"code": "200 OK", "new_comment_id": new_comment.id}) ...
新引入的JsonResponse返回的是json格式的數(shù)據(jù),由它將新評論的id傳遞出去。
json是web開發(fā)中很常用的輕量級數(shù)據(jù)格式,非常像python的字典,讀者請自行了解。特別提醒json格式必須用雙引號。
現(xiàn)在數(shù)據(jù)在iframe中了。但是我們需要刷新的是iframe的父頁面啊,所以還要繼續(xù)把數(shù)據(jù)往父頁面“扔"。
修改二級評論的模板:
templates/comment/reply.html ...
由于現(xiàn)在ajax獲取的是json數(shù)據(jù),因此用e.code獲取視圖返回的狀態(tài)。
舊代碼用parent.location.reload()刷新了父頁面。同樣的,用parent.abc()可以調用父頁面的abc()函數(shù)。這樣就把數(shù)據(jù)傳遞到父頁面里去了。
這下就好說了。在父頁面中(文章詳情模板)添加需要執(zhí)行錨點拼接的函數(shù):
templates/article/detail.html ... {% block script %} ... {% endblock script %}
函數(shù)中運用了JavaScript的三元運算符a ? b : c,翻譯成人話就是:如果a成立則返回b,如果a不成立就返回c。作用是去掉url尾部的/,否則錨點不會生效。你可能會問,三元運算符多麻煩,為什么不直接把url末尾一個字符剔除掉呢?答案是這樣寫代碼更加健壯。萬一哪天Django解析的url尾部沒有斜杠了呢。
window.location.replace()作用是重定向頁面,在這里面終于可以愉快的拼接錨點了。
一切都OK啦。測試發(fā)表二級評論,運氣好的同學應該可以順利將視窗定位到剛評論的位置了。
感受到數(shù)據(jù)的流動沒有?
總結本章學習了錨點的html拼接、視圖拼接、ajax+iframe綜合運用,理解后就能應付絕大部分的狀況了。
錨點雖然古老,但并不陳舊。
合理的運用錨點,可以讓你的博客相當?shù)娜诵曰?,這也是好網(wǎng)站的一個標志。
有疑問請在杜賽的個人網(wǎng)站留言,我會盡快回復。
或Email私信我:[email protected]
項目完整代碼:Django_blog_tutorial
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://systransis.cn/yun/43948.html
摘要:博文也是同樣的,好的目錄對博主和讀者都很有幫助。文中的目錄之前我們已經(jīng)為博文支持了語法,現(xiàn)在繼續(xù)增強其功能。修改文章詳情視圖文章詳情目錄擴展僅僅是將將擴展添加了進去。通過將目錄傳遞給模板。 對會讀書的人來說,讀一本書要做的第一件事,就是仔細閱讀這本書的目錄。閱讀目錄可以對整體內容有所了解,并清楚地知道感興趣的部分在哪里,提高閱讀質量。 博文也是同樣的,好的目錄對博主和讀者都很有幫助。更...
摘要:創(chuàng)建在中的一個代表一個功能模塊。就是項目的基石,因此開發(fā)博客的第一步就是創(chuàng)建新的,用來實現(xiàn)跟文章相關的功能模塊。注意之后,的必須配置,否則會報錯??偨Y本章創(chuàng)建了博客文章功能的,學習了注冊并配置。 創(chuàng)建APP 在Django中的一個app代表一個功能模塊。開發(fā)者可以將不同功能的模塊放在不同的app中, 方便代碼的復用。app就是項目的基石,因此開發(fā)博客的第一步就是創(chuàng)建新的app,用來實現(xiàn)...
摘要:改寫視圖函數(shù)上一章我們感受了視圖的工作流程。循壞表示依次取出中的元素,命名為,并分別執(zhí)行接下來操作。即為語言,中間包裹了一個段落的文字。有疑問請在杜賽的個人網(wǎng)站留言,我會盡快回復。 改寫視圖函數(shù) 上一章我們感受了視圖的工作流程。 為了讓視圖真正發(fā)揮作用,改寫article/views.py中的article_list視圖函數(shù): article/views.py from django...
摘要:有了文章列表頁面后,當然還需要詳情頁面,方便用戶對某一篇感興趣的文章深入閱讀。編寫視圖函數(shù)打開,增加文章詳情頁面的視圖函數(shù)文章詳情取出相應的文章需要傳遞給模板的對象載入模板,并返回對象函數(shù)中多了這個參數(shù)。 有了文章列表頁面后,當然還需要詳情頁面,方便用戶對某一篇感興趣的文章深入閱讀。 編寫視圖函數(shù) 打開article/views.py,增加文章詳情頁面的視圖函數(shù)article_deta...
摘要:接下來你就可以在項目的任何地方發(fā)送通知了像這樣其中的參數(shù)釋義發(fā)送通知的對象接收通知的對象動詞短語鏈接到動作的對象可選執(zhí)行通知的對象可選有點繞,舉個栗子杜賽在搭建個人博客中對你發(fā)表了評論。有疑問請在杜賽的個人網(wǎng)站留言,我會盡快回復。 憑借你勤奮的寫作,拜讀你文章的用戶越來越多,他們的評論也分散在眾多的文章之中。作為博主,讀者的留言肯定是要都看的;而讀者給你留言,自然也希望得到回復。 怎么...
閱讀 582·2023-04-25 16:00
閱讀 1624·2019-08-26 13:54
閱讀 2504·2019-08-26 13:47
閱讀 3443·2019-08-26 13:39
閱讀 1061·2019-08-26 13:37
閱讀 2751·2019-08-26 10:21
閱讀 3545·2019-08-23 18:19
閱讀 1611·2019-08-23 18:02