站内通知使用django-notifications-hq第三方库。执行如下命令安装django-notifications-hq:
执行命令后,安装3个库。对应名称和版本如下,若你测试代码有问题,请参考最新帮助文档或源码:
1)django-model-utils=3.0.0
2)django-notifications-hq=1.2
3)jsonfield=2.0.1
可以在Python安装目录Lib/site-packages找到notifications。以下开发基本都是查看notifications源码和其Github的帮助。网上的文章还是抄来抄去,毫无新意和用处。
接着,打开Django项目的settings.py文件,在INSTALLED_APPS加入该应用:
INSTALLED_APPS = [
# ... 其他省略不写
'notifications',
]
再更新数据库,由于notifications已经makemigrations了,直接migrate更新同步数据库:
python manage.py migrate notifications
再打开urls.py总路由设置,添加notifications的urls
import notifications.urls
path('notifications/', include(notifications.urls, namespace='notifications')), #站内消息互通
本文以评论通知为例,进行实例练习:
1.新建一个消息显示html页面
<div class="panel-body"> {% for i in request.user.notifications.all %} <ui style="list-style-type:none"> <li><h4>{{ i.timestamp }}</h4>{{ i.verb|safe }}</li> </ui> {% empty %} <p>暂未收到消息</p> {% endfor %} </div>
request.user.notifications.all 方法获取这个用户的全部消息
2.新建显示消息的视图
from django.contrib.auth.decorators import login_required
@login_required
#用户消息展示视图 def xiaoxi(request): return render(request,'user/xiaoxi.html')
3.新建url
path('xx/', xiaoxi, name='xx'),#消息路由
4.在登录显示成功后,添加一个连接
<li><a href="{% url 'xx' %}">消息中心</a></li>
5.在处理评论的视图里这样写:
from notifications.signals import notify #消息通知
@login_required #评论处理视图 def comment_post(request):
..... com_post.save() #发送消息通知 # notify.send(发送者, recipient=接收者, verb='传递的简短内容(传递长文查看官网换关键字)') notify.send(author, recipient=post.author, verb='你的名为<b>%s</b>的文章被<b>%s</b>评论了, <a href="%s">前往查看</a>'% (post.title,author,post_url))
效果图:
到这一步,已经可以很好的展示效果了,我们可以千万需要的地方,模仿这样写代码,比如用户注册,评论被回复,用户登录,站在广播等都可以使用。
下一步,我们来优化这些功能,比如,显示有多少条消息没有读:
在实际使用通知标记之前,将{%load notifications_tags%}放在模板中。
{% load notifications_tags %}
{% if request.user.is_authenticated %} <li><a href="#">欢迎:{{ user.username }}</a></li> {% notifications_unread as unread_count %} {% if unread_count %} <li><a href="{% url 'xx' %}">消息中心({{ unread_count }})</a></li> {% else %} <li><a href="{% url 'xx' %}">消息中心(0)</a></li> {% endif %}
在消息中心将消息标记为已读:
1.批量标记为已读:
在消息展示页面:
{% load notifications_tags %}
<div class="unread_head"> {% notifications_unread as unread_count %} <span>您共有{{unread_count}}条未读消息</span> <a class="btn btn-info unread_btn" href="{% url 'xxyd' %}"> 全部标记为已读 </a> </div>
2.新建处理视图
#全部标记为已读消息 @login_required def user_mark_all_read(request): user = request.user notifies = user.notifications.all() notifies.mark_all_as_read() # 标记所有未读为已读 return redirect(reverse('xx')) # 重定向回用户中心
3.新建路由
path('xxyd/', user_mark_all_read, name='xxyd'),#消息已读路由
4.如果有人对你的评论进行了回复,如何才能收到站内消息通知呢?总体方法都是一样的,但有几个地方要注意一下:
(1)怎么获取被评论对象。
我是这样做到,我在回复按钮处,将被评论者ID传到评论回复视图
<a href="{% url 'huifu' node.id post.id node.comment_author.pk %}?next={{ request.get_full_path }}">回复</a>
(2)URL 要添加一个变量
path('huifu/<int:is_who_id>/<int:wenzhang_id>/<int:bplz>/',comment_post_two,name='huifu'), #文章回复路由
(3)试图也要添加,并传递过去
@login_required #评论的回复页面展示视图 def comment_post_two(request,wenzhang_id,is_who_id,bplz): post_urls = request.GET.get('next') # 获取url上携带的来源地址,用于登录后跳转回去! print(bplz) comment_post = CommentForm(initial={'post_title':wenzhang_id,'parent':is_who_id,'comment_author':request.user.id,'bplz':bplz}) return render(request,'comments/pinglun.html',{'comment_post':comment_post,'post_urls':post_urls})
(4)验证表单添加一个字段,注意:这里添加量字段,主评论窗口,渲染的时候,要传递一个空,不然报302
主评视图:
#实例评论窗口
comment_Form = CommentForm(initial={'comment_author':request.user.id,'post_title':post_id,'parent':'Null','bplz':'Null'})
#html里
{{ content_form.bplz }}
#验证表单
class CommentForm(forms.Form):
text = forms.CharField(label='评论',min_length=3,max_length=200,widget=CKEditorWidget(config_name='qianduan_ckeditor',attrs={'class':'form-control'}))
post_title = forms.CharField(widget=forms.HiddenInput())
comment_author=forms.CharField(widget=forms.HiddenInput())
parent=forms.CharField(widget=forms.HiddenInput())
bplz=forms.CharField(widget=forms.HiddenInput())
(5)回复处理视图
@login_required def comment_post_three(request):
......
# 发送消息通知 # notify.send(发送者, recipient=接收者, verb='传递的简短内容(传递长文查看官网换关键字)') notify.send(author, recipient=bplz_user,verb='你发表在文章【%s】的评论被【%s】回复了,<a href="%s">前往查看</a>'%(post,author.last_name,post_urls)) #跳转或来之前的页面,如果获取不到,就重定向到首页
为消息中心添加一个删除全部已读消息的按键和后台处理视图
html:
<div class="unread_head"> {% notifications_unread as unread_count %} <span>您共有<span class="badge">{{ unread_count }}</span>条未读消息</span> <a class="btn btn-info unread_btn" href="{% url 'xxyd' %}"> 全部标记为已读 </a> <a href="{% url 'xxydel' %}" class="btn btn-info btn-danger">删除全部已读消息</a> </div> {% for i in request.user.notifications.all %} <ui style="list-style-type:none"> {% if i.unread %} <li style="color:black"><h4>{{ i.timestamp }}</h4>{{ i.verb|safe }}</li> {% else %} <li style="color: #bbbbbb"><h4>{{ i.timestamp }}</h4>{{ i.verb|safe }}</li> {% endif %} </ui> {% empty %} <p>暂未收到消息</p> {% endfor %} </div>
视图:
#删除全部已读消息 @login_required def user_mark_all_del(request): #获取全部已读 notifies=request.user.notifications.read() notifies.delete() return redirect(reverse('xx')) # 重定向回用户中心
url
path('xxdel/', user_mark_all_del, name='xxydel'),#删除已读消息路由
0
登陆后方可评论