博客动态
Hi!欢迎来到Jerry Coding!公众号垃圾分类增加学习功能,关注下面的公众号一起来帮助Jerry学习更多垃圾分类知识吧!
微信扫码

扫一扫关注我

More
关于
New
RSS

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

2018年12月28日 Jerry 2510 2019年6月22日

话不多说,直接开干!

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

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

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

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>

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

 

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

       当前的消息是我们后台管理员手动添加的,如何实现评论后自动创建通知呢?这里使用了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()

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

 

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


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

微信
支付宝

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

0 人参与 | 0 条评论