django-notifications-hq 实现站内用户间消息互通


发布时间:2019-02-15 13:08    作者: Uncle Hui   已过去:1 年,7 月   阅读总量:1239 已被赞:0


官网文档:https://pypi.org/project/django-notifications-hq/

1、安装Notifications

站内通知使用django-notifications-hq第三方库。执行如下命令安装django-notifications-hq:

  1. pip install 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




登陆后方可评论