Django 如何实现帖子收到新点赞后向作者发送通知
实现方案
首先明确前提:Django原生messages框架仅支持向当前请求会话的登录用户推送单次消息,无法跨会话直接给未在线的帖子作者发通知,所以需要搭配轻量的通知存储模型实现需求,完整步骤如下:
1. 创建通知存储模型
在对应App的models.py中新增通知模型,用来持久化存储未读的点赞通知:
from django.db import models from django.contrib.auth import get_user_model from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.models import ContentType User = get_user_model() class Notification(models.Model): NOTIFICATION_TYPES = ( ('like', '点赞'), # 后续可扩展评论、关注等其他通知类型 ) recipient = models.ForeignKey(User, on_delete=models.CASCADE, related_name='notifications', verbose_name='通知接收人') sender = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='通知触发人') notification_type = models.CharField(max_length=20, choices=NOTIFICATION_TYPES) content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) object_id = models.PositiveIntegerField() content_object = GenericForeignKey('content_type', 'object_id') is_read = models.BooleanField(default=False) created_at = models.DateTimeField(auto_now_add=True)
编写完成后执行python manage.py makemigrations和python manage.py migrate同步数据库结构。
2. 点赞逻辑中新增通知生成逻辑
在你已完成的点赞接口中,post.save()执行之后新增创建通知的代码,跳过自己给自己点赞的场景避免无效通知:
# 原有点赞逻辑,假设当前登录用户为request.user,被点赞的帖子对象为post if 点赞操作校验通过: post.save() if request.user != post.author: Notification.objects.create( recipient=post.author, sender=request.user, notification_type='like', content_object=post )
3. 中间件配合messages实现通知推送
编写全局中间件,在每个登录用户发起请求时拉取他的未读通知推送到messages队列,同时标记为已读避免重复推送:
首先在App目录下新建middleware.py:
from django.contrib import messages from .models import Notification class NotificationMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): # 仅处理登录用户的请求 if request.user.is_authenticated: # 拉取当前用户所有未读的点赞通知 unread_likes = Notification.objects.filter( recipient=request.user, notification_type='like', is_read=False ) for notice in unread_likes: messages.info(request, f"{notice.sender.username} 点赞了你的帖子") # 批量标记为已读 unread_likes.update(is_read=True) response = self.get_response(request) return response
之后在settings.py的MIDDLEWARE列表中注册该中间件,注意必须放在SessionMiddleware和AuthenticationMiddleware之后:
MIDDLEWARE = [ # ... 原有默认中间件 'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', # 新增自定义通知中间件,替换your_app_name为你的App实际名称 'your_app_name.middleware.NotificationMiddleware', # ... 其他中间件 ]
4. 前端模板渲染通知
在全站共用的基础模板中添加messages渲染代码,所有推送的通知都会在该位置展示:
{% if messages %} {% for message in messages %} <div class="notice-alert {{ message.tags }}"> {{ message }} </div> {% endfor %} {% endif %}
如果需要实现类似Instagram的顶部悬浮自动消失效果,给上述标签添加对应的CSS样式和JS自动隐藏逻辑即可。
如果需要实现在线用户实时接收通知(不需要等待刷新页面),可以在上述方案基础上搭配WebSocket组件,常规场景下上述方案完全可以满足需求,且全部基于Django原生组件实现,不需要引入额外第三方依赖。
内容的提问来源于stack exchange,提问作者Dariun
相关产品推荐
相关产品推荐

