摘要:接下來你就可以在項目的任何地方發(fā)送通知了像這樣其中的參數(shù)釋義發(fā)送通知的對象接收通知的對象動詞短語鏈接到動作的對象可選執(zhí)行通知的對象可選有點繞,舉個栗子杜賽在搭建個人博客中對你發(fā)表了評論。有疑問請在杜賽的個人網(wǎng)站留言,我會盡快回復(fù)。
憑借你勤奮的寫作,拜讀你文章的用戶越來越多,他們的評論也分散在眾多的文章之中。作為博主,讀者的留言肯定是要都看的;而讀者給你留言,自然也希望得到回復(fù)。
怎么將未讀的留言呈現(xiàn)給正確的用戶呢?總不能用戶自己去茫茫文章中尋找吧,那也太蠢了。給評論增加通知功能就是很流行的解決方案:比如微信朋友圈留言的通知、新浪微博留言的通知、以及各種社交平臺的“小紅點”。
本篇將以django-notifications為基礎(chǔ),非常高效的搭建一個簡易的通知系統(tǒng)。
發(fā)送通知前面的步驟我們已經(jīng)很熟悉了。
首先安裝django-notifications:
(env) > pip install django-notifications-hq
注冊app:
my_blog/settings.py ... INSTALLED_APPS = [ ... "notifications", ... ] ...
在根路由中安裝路徑:
my_blog/urls.py ... import notifications.urls urlpatterns = [ ... path("inbox/notifications/", include(notifications.urls, namespace="notifications")), ... ] ...
注意這里的notifications.urls沒有像之前一樣用字符串,是為了確保模塊安裝到正確的命名空間中。
數(shù)據(jù)遷移:
(env) > python manage.py migrate
app就安裝好了。
接下來你就可以在項目的任何地方發(fā)送通知了!像這樣:
from notifications.signals import notify notify.send(actor, recipient, verb, target, action_object)
其中的參數(shù)釋義:
actor:發(fā)送通知的對象
recipient:接收通知的對象
verb:動詞短語
target:鏈接到動作的對象(可選)
action_object:執(zhí)行通知的對象(可選)
有點繞,舉個栗子:杜賽 (actor) 在 Django搭建個人博客 (target) 中對 [你]() (recipient) [發(fā)表了]() (verb) [評論]() (action_object)。
因為我們想要在用戶發(fā)表評論的時候發(fā)送通知,因此修改一下發(fā)表評論的視圖:
comments/views.py ... from notifications.signals import notify from django.contrib.auth.models import User ... def post_comment(...): ... # 已有代碼,創(chuàng)建新回復(fù) if comment_form.is_valid(): ... # 已有代碼,二級回復(fù) if parent_comment_id: ... # 新增代碼,給其他用戶發(fā)送通知 if not parent_comment.user.is_superuser: notify.send( request.user, recipient=parent_comment.user, verb="回復(fù)了你", target=article, action_object=new_comment, ) return HttpResponse("200 OK") new_comment.save() # 新增代碼,給管理員發(fā)送通知 if not request.user.is_superuser: notify.send( request.user, recipient=User.objects.filter(is_superuser=1), verb="回復(fù)了你", target=article, action_object=new_comment, ) return redirect(article) ...
2019/6/4 修正此代碼。舊代碼錯誤的將發(fā)送給管理員的notify放在了new_comment.save()的前面,導(dǎo)致action_object存儲為NULL。
增加了兩條notify的語句,分別位于兩個if語句中:
第一個notify:用戶之間可以互相評論,因此需要發(fā)送通知。if語句是為了防止管理員收到重復(fù)的通知。
第二個notify:所有的評論都會給管理員(也就是博主)發(fā)送通知,除了管理員自己。
其他的代碼沒有變化,注意位置不要錯就行了。你可以試著發(fā)送幾條評論,然后打開SQLiteStudio,查看notifications_notification表中的數(shù)據(jù)變化。
有效代碼實際上只有4行,我們就完成了創(chuàng)建、發(fā)送通知的功能!相信你已經(jīng)逐漸體會到運(yùn)用第三方庫帶來的便利了。這就是站在了“巨人們”的肩膀上。小紅點
后臺創(chuàng)建通知的邏輯已經(jīng)寫好了,但是如果不能在前端顯示出來,那也沒起到作用。
而前端顯示消息通知比較流行的是“小紅點”,流行得都已經(jīng)泛濫了,盡管很多軟件其實根本就不需要。另一種形式是消息徽章,即一個紅色方框中帶有消息條目的計數(shù)。這兩種方式都會用到博客頁面中。
在位置的選擇上,header是很合適的,因為它在博客的所有位置都會顯示,很符合通知本身的定位。
因此修改header.html:
templates/header.html {% load notifications_tags %} {% notifications_unread as unread_count %} ...
django-notifications自帶簡易的模板標(biāo)簽,可以在前臺模板中調(diào)用重要的通知相關(guān)的對象,在頂部引入就可以使用了。比如unread_count是當(dāng)前用戶的未讀通知的計數(shù)。
Bootstrap自帶有徽章的樣式,但是卻沒有小紅點的樣式(至少我沒有找到),所以就只能用svg自己畫了,好在也不難。
svg是繪制矢量圖形的標(biāo)簽,這里就不展開講了,感興趣請自行搜索相關(guān)文章。
隨便評論幾條,刷新頁面看一看:
效果不錯。但是鏈接的href是空的,接下來就處理。
未讀與已讀既然是通知,那么肯定能夠分成”未讀的“和”已讀的“兩種。在適當(dāng)?shù)臅r候,未讀通知又需要轉(zhuǎn)換為已讀的。現(xiàn)在我們來開發(fā)功能集中處理它。
通知是一個獨(dú)立的功能,以后有可能在任何地方用到,放到評論app中似乎并不合適。
所以新建一個app:
(env) > python manage.py startapp notice
注冊:
my_blog/settings.py ... INSTALLED_APPS = [ ... "notice", ] ...
根路由:
my_blog/urls.py ... urlpatterns = [ ... # notice path("notice/", include("notice.urls", namespace="notice")), ] ...
接下來就是視圖了。之前所有的視圖都是用的視圖函數(shù),這次我們更進(jìn)一步,用類視圖來完成。忘記什么是類視圖的,回憶一下前面類的視圖章節(jié)。
編寫視圖:
notice/views.py from django.shortcuts import render, redirect from django.views import View from django.views.generic import ListView from django.contrib.auth.mixins import LoginRequiredMixin from article.models import ArticlePost class CommentNoticeListView(LoginRequiredMixin, ListView): """通知列表""" # 上下文的名稱 context_object_name = "notices" # 模板位置 template_name = "notice/list.html" # 登錄重定向 login_url = "/userprofile/login/" # 未讀通知的查詢集 def get_queryset(self): return self.request.user.notifications.unread() class CommentNoticeUpdateView(View): """更新通知狀態(tài)""" # 處理 get 請求 def get(self, request): # 獲取未讀消息 notice_id = request.GET.get("notice_id") # 更新單條通知 if notice_id: article = ArticlePost.objects.get(id=request.GET.get("article_id")) request.user.notifications.get(id=notice_id).mark_as_read() return redirect(article) # 更新全部通知 else: request.user.notifications.mark_all_as_read() return redirect("notice:list")
視圖共兩個。
CommentNoticeListView:繼承自ListView,用于展示所有的未讀通知。get_queryset方法返回了傳遞給模板的上下文對象,unread()方法是django-notifications提供的,用于獲取所有未讀通知的集合。另外視圖還繼承了“混入類”LoginRequiredMixin,要求調(diào)用此視圖必須先登錄。
CommentNoticeUpdateView:繼承自View,獲得了如get、post等基礎(chǔ)的方法。mark_as_read()、mark_all_as_read都是模塊提供的方法,用于將未讀通知轉(zhuǎn)換為已讀。if語句用來判斷轉(zhuǎn)換單條還是所有未讀通知。
重復(fù):閱讀有困難的同學(xué),請重新閱讀類的視圖查閱。
接下來就是新建urls.py了,寫入:
notice/urls.py from django.urls import path from . import views app_name = "notice" urlpatterns = [ # 通知列表 path("list/", views.CommentNoticeListView.as_view(), name="list"), # 更新通知狀態(tài) path("update/", views.CommentNoticeUpdateView.as_view(), name="update"), ]
path()的第二個參數(shù)只能接收函數(shù),因此別忘了要調(diào)用類視圖的as_view()方法。
集中處理通知需要一個多帶帶的頁面。新建templates/notice/list.html模板文件:
templates/notice/list.html {% extends "base.html" %} {% load staticfiles %} {% block title %} 通知 {% endblock title %} {% block content %}{% endblock content %}{% for notice in notices %}
- {{ notice.actor }} 在 {{ notice.target }} {{ notice.verb }}。 {{ notice.timestamp|date:"Y/m/d H:i" }}
{% endfor %}
模板中主要提供了兩個功能:
點擊button按鈕清空所有未讀通知
點擊單個通知,將其轉(zhuǎn)換為已讀通知,并前往此評論所在的文章
末尾標(biāo)簽中的偽類選擇器,作用是將已經(jīng)點擊過的通知字體顏色轉(zhuǎn)換為淺灰色,優(yōu)化用戶體驗。
最后就是補(bǔ)上入口:
templates/header.html ... 通知... ...
這樣就完成了。
打開服務(wù)器,用一個普通賬號評論幾條,再登錄管理員賬號并進(jìn)入通知頁面:
就能看到不錯的效果了。實現(xiàn)的效果是僅展示未讀通知,當(dāng)然也可以在下邊展示已讀通知,方便用戶追溯。
總結(jié)通知功能非常的重要,特別是在你的博客成長壯大了之后。你還可以把它用在別的地方,比如每新發(fā)表一篇文章,就給你所有的“粉絲”推送一條通知,提醒他們可以來拜讀了。具體如何擴(kuò)展運(yùn)用,就靠你腦洞大開了。
課后作業(yè):前面的代碼中,如果用戶自己評論自己,同樣也會收到通知。這種通知并沒有必要,請修正它。
遇到困難,在教程示例代碼找答案吧。
有疑問請在杜賽的個人網(wǎng)站留言,我會盡快回復(fù)。
或Email私信我:dusaiphoto@foxmail.com
項目完整代碼:Django_blog_tutorial
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/43828.html
摘要:在父頁面中文章詳情模板添加需要執(zhí)行錨點拼接的函數(shù)新增函數(shù),處理二級回復(fù)去除尾部符號刷新并定位到錨點函數(shù)中運(yùn)用了的三元運(yùn)算符,翻譯成人話就是如果成立則返回,如果不成立就返回。 老讀者注意:上一章消息通知有個bug,即發(fā)給管理員的notify必須移動到new_comment.save()的后面,否則會導(dǎo)致action_object存儲為NULL,并且導(dǎo)致本章的html拼接錨點失效。原文已...
摘要:每一條日志記錄也包含級別,代表對應(yīng)消息的嚴(yán)重程度。即格式化器,主要功能是確定最終輸出的形式和內(nèi)容。最好是日志能夠按自然天進(jìn)行記錄和分割。 上一章學(xué)習(xí)了自動化測試,很好,現(xiàn)在我們可以絞盡腦汁寫出一份全面的測試,來保證代碼永遠(yuǎn)健康了。 話雖如此,但是作為一個獨(dú)立開發(fā)者很難寫出真正全面的測試代碼。這是因為用戶在使用你的網(wǎng)站時可不會循規(guī)蹈矩,而是會以各種怪異的姿勢瀏覽網(wǎng)頁、上傳數(shù)據(jù)。但這也不是...
摘要:本章講如何幫助健忘癥患者,重置用戶密碼。實際上不僅內(nèi)置了密碼重置,還包括登錄登出密碼修改等功能。總結(jié)本章學(xué)習(xí)了使用第三方庫,高效完成了重置密碼的功能。有疑問請在杜賽的個人網(wǎng)站留言,我會盡快回復(fù)。 隨著技術(shù)的發(fā)展,驗證用戶身份的手段越來越多,指紋、面容、聲紋應(yīng)有盡有,但密碼依然是最重要的手段。 互聯(lián)網(wǎng)處處都有密碼的身影,甚至變成了現(xiàn)代人的一種負(fù)擔(dān)。像筆者這樣的,動輒幾十個賬號密碼,忘記其...
摘要:博客網(wǎng)站的用戶信息并不復(fù)雜,因此擴(kuò)展就足夠了。可以在這個基礎(chǔ)上,擴(kuò)展為一個美觀詳細(xì)的用戶信息頁面。當(dāng)然最好再給個人信息添加一個入口。沒有對用戶的登錄狀態(tài)進(jìn)行檢查??偨Y(jié)本章使用一對一鏈接的方式,擴(kuò)展并更新了用戶信息。 可能你已經(jīng)發(fā)現(xiàn)了,Django自帶的User模型非常實用,以至于我們沒有寫用戶管理相關(guān)的任何模型。 但是自帶的User畢竟可用的字段較少。比方說非常重要的電話號碼、頭像等都...
摘要:用實現(xiàn)一個更實用的博客系統(tǒng),讓寫作更簡單,更愉快。博客相關(guān)頁面博客首頁博文詳情后臺管理相關(guān)頁面后臺首頁添加文章文章列表標(biāo)簽管理分類管理系統(tǒng)消息用戶列表友鏈管理用戶個人信息全局設(shè)置普通用戶登錄所看到的頁面環(huán)境后臺模板后記看到這兒是不是已經(jīng)迫不 July 用Django實現(xiàn)一個更實用的博客系統(tǒng),讓寫作更簡單,更愉快。 Demo 博客相關(guān)頁面 博客首頁 showImg(https://se...
閱讀 2648·2021-11-12 10:36
閱讀 2291·2021-08-23 09:47
閱讀 1734·2019-08-30 15:44
閱讀 1431·2019-08-30 14:10
閱讀 2265·2019-08-29 16:52
閱讀 2364·2019-08-29 16:40
閱讀 1611·2019-08-29 16:17
閱讀 2438·2019-08-26 13:21