Django建站历程:(十二)signal自动消息通知

2018年12月27日 Jerry 7148 2021年1月17日

话不多说,直接开干!

1、添加model属性

      一个评论的提示消息属性大约有以下几点:消息所属评论、消息创建时间、消息发送者、消息接收者、消息是否已读。修改app/comment/models.py,创建评论的相关属性字段如下

class Message(models.Model):
    sender = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='sender_message', verbose_name='发送者')
    receiver = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='receiver_message', verbose_name='接收者')
    create_date = models.DateTimeField('创建时间', auto_now_add = True)
    is_read = models.BooleanField('是否已读', default = False)

    belong = models.ForeignKey(Comment, on_delete=models.CASCADE, related_name='comment_messages', verbose_name='所属评论')

    class Meta:
        verbose_name = '消息通知'
        verbose_name_plural = verbose_name
        ordering = ['-create_date']

    def mark_read(self):
        self.is_read = True
        self.save(update_fields=['is_read'])

2、修改admin.py

修改如下代码用于消息字段的后台显示

from comment.models import Message

@admin.register(Message)
class CommentAdmin(admin.ModelAdmin):
    list_display = ['id', 'sender', 'receiver', 'create_date','belong']                               

3、同步数据库

root@jerryls-site1:/home/mysite# ./manage.py makemigrations
root@jerryls-site1:/home/mysite# ./manage.py migrate

此时,运行服务器进入后台即可看到消息字段

jerrycoding Django建站历程:(十二)signal自动消息通知

我们能先随便加一条评论用于显示。

jerrycoding Django建站历程:(十二)signal自动消息通知

4、创建模板文件

       我们创建消息模板文件msg_list_all.html显示全部消息,创建消息模板文件msg_list_unread.html显示未读消息。页面大体分两列,左边是具体消息列表,右侧供用户选择过滤全部消息、未读消息。路径老规矩,在app/comment/templates/comment/下。代码类似文章列表的显示:

{% extends "blog/base.html" %}
{% block base_content %}

<div class="container">
    <div class="row">
        <div class="col-lg-8 col-xs-12 col-sm-6 col-md-8">
           <div class="list-group">
             <a class="list-group-item disabled">消息通知</a>
             {% for msg in msg_list %}
             <span class="list-group-item">{{msg.sender}} 在《<a href="{% url 'blog:article_url' msg.belong.belong.slug %}">{{msg.belong.belong.title}}</a>》中提到了你
             </span>
             {% empty %}
             <h3>暂无消息!</h3>
             {% endfor %}
           </div>
        </div>

        <!-- Right -->
        <div class=" col-lg-4 col-xs-12 col-sm-6">
          <div class="list-group">
             <a class="list-group-item disabled">消息通知</a>
             <a href="{% url 'comment:msg_all_url' %}" class="list-group-item">全部消息</a>
             <a href="{% url 'comment:msg_unread_url' %}" class="list-group-item">未读消息</a>
          </div>

        </div>
    </div>
</div>

{% endblock %}

5、添加视图和路由

from .models import Message

@login_required
def msg_all_view(request):
    msg_list = Message.objects.filter(receiver = request.user)
    return render(request, 'comment/msg_list.html',{'msg_list':msg_list})

@login_required
def msg_unread_view(request):
    msg_list = Message.objects.filter(receiver = request.user)
    msg_list2 = []
    for msg in msg_list:    
        if msg.is_read == False:
            msg_list2.append(msg)

    return render(request, 'comment/msg_list.html',{'msg_list':msg_list2})
from django.urls import path
from .views import cmt_add_view, msg_all_view, msg_unread_view

app_name = '[comment]'

urlpatterns = [
    path('add/',cmt_add_view, name='cmt_add_url'),  # 添加评论:
    path('message/all',msg_all_view, name='msg_all_url'),  # 所有消息
    path('message/unread',msg_unread_view, name='msg_unread_url'),  # 未读消息
]

最后在用户登陆成功的下拉列表添加消息通知按钮,方便跳转:

<li><a href="{% url 'comment:msg_all_url' %}">消息通知</a></li>

运行服务器,点击消息通知便可以看到消息列表了。

 jerrycoding Django建站历程:(十二)signal自动消息通知

点击文章名字还可以跳转到文章界面。关于消息的删除和标记已读,我这里就不写了,可以参考提交评论的实现。

       当前的消息是我们后台管理员手动添加的,如何实现评论后自动创建通知呢?这里使用了django的signal机制:当一条新评论save()后,发送signal来创建一条新消息保存至数据库。关于siganl的详细介绍,可以参考 django-signal

6、添加信号处理view

实现逻辑很简单,代码也不多,在views.py中添加以下即可:

from django.db.models.signals import post_save
from django.dispatch import receiver

@receiver(post_save, sender=Comment) #只接收comment发来的post_save消息
def create_msg_handler(sender, instance, **kwargs):
    article = instance.belong   # instance 就是发信号的对象,这里是个评论
    sender = instance.owner     # 获取评论者,即消息发送者
    receiver = article.author   # 通知文章作者
    msg = Message(sender=sender, receiver=receiver, belong=instance)  # 新建消息保存
    msg.save()

最终效果如下:评论了《葫芦娃》后,点击未读消息即可看到消息。

jerrycoding Django建站历程:(十二)signal自动消息通知

jerrycoding Django建站历程:(十二)signal自动消息通知

 

      至此,消息通知基本完成。这里做了简化,其实消息可以通知作者,也可以通知评论者,甚至评论或者回复后可以发邮件给用户等等。大家自己慢慢折腾吧~


《django 建站历程系列文章》

(一)服务器的选取与环境准备

(二)创建第一个project和app

(三)创建并显示博客的主页导航栏

(四)django-allauth实现用户登陆

(五)django-allauth实现第三方登陆

(六)使用bootstrap3美化登陆界面

(七)添加用户签名字段

(八)自定义用户头像

(九)发布我的第一篇博客

(十)CKEditor的配置使用

(十一)ajax实现文章添加评论

(十二)signal自动消息通知

(十三)基于django-haystack的全文搜索

(十四)配置SSL证书实现网站HTTPS访问

(十五)免费开启七牛云CDN加速

(十六)particles 粒子背景插件

(十七)集成 xadmin2 后台管理

(十八)RestFramework 编写API

(十九)Nginx+uwsgi 部署 django

(二十)自定义网站404界面

(二一)jwt为API添加身份认证

jerrycoding 博客源码大公开


原创文章,转载请注明出处: https://jerrycoding.com/article/site_building_12

微信
jerry微信赞助
支付宝
jerry支付宝赞助

您尚未登录,暂时无法评论。请先 登录 或者 注册

0 人参与 | 0 条评论