You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 23:45:03