You need to enable JavaScript to run this app. Django实现帖子@提及用户的通知及消息管理功能
优惠活动
大模型
产品
解决方案
定价
更多

Django实现帖子@提及用户的通知及消息管理功能

基于Django的@提及通知可落地实现方案

基础Notification模型定义

不要为了追求通用做过度抽象,直接贴合当前提及通知的需求定义字段即可,参考实现如下:

# notifications/models.py
from django.db import models
from django.conf import settings
from posts.models import Post

class Notification(models.Model):
    NOTIFICATION_TYPES = (
        ("mention", "内容提及"),
    )
    # 接收通知的用户
    recipient = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name="received_notifications"
    )
    # 触发通知的用户(也就是发布内容、提及别人的用户)
    triggered_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name="triggered_notifications"
    )
    # 关联触发通知的具体帖子
    related_post = models.ForeignKey(
        Post,
        on_delete=models.CASCADE
    )
    # 通知类型,后续扩展评论、点赞通知可以直接加选项
    notification_type = models.CharField(
        max_length=20,
        choices=NOTIFICATION_TYPES,
        default="mention"
    )
    # 是否已读标记
    is_read = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        # 默认按创建时间倒序,最新通知排最前
        ordering = ["-created_at"]

@提及匹配与通知生成辅助函数

用轻量正则匹配内容里的@username片段,匹配规则和Django默认User模型的username字段规则保持一致,避免出现匹配到标点、邮箱片段的问题,参考实现:

# notifications/utils.py
import re
from django.contrib.auth import get_user_model
from .models import Notification

User = get_user_model()
# 匹配规则:@开头,后接字母、数字、下划线,和默认用户名规则对齐
MENTION_PATTERN = re.compile(r"@([a-zA-Z0-9_]+)")

def create_mention_notifications(post):
    # 从帖子内容里提取所有匹配的@片段
    mentioned_usernames = MENTION_PATTERN.findall(post.content)
    # 先对用户名去重,避免同一篇内容里多次@同一个用户生成重复通知
    mentioned_usernames = list(set(mentioned_usernames))

    for username in mentioned_usernames:
        # 查找被提及的用户是否真实存在
        try:
            mentioned_user = User.objects.get(username=username)
        except User.DoesNotExist:
            continue
        # 跳过自己提及自己的场景,避免冗余通知
        if mentioned_user == post.author:
            continue
        # 跳过已经生成过的同内容提及通知,适配用户编辑帖子的场景
        if Notification.objects.filter(
            recipient=mentioned_user,
            related_post=post,
            notification_type="mention"
        ).exists():
            continue
        # 生成正式的通知记录
        Notification.objects.create(
            recipient=mentioned_user,
            triggered_by=post.author,
            related_post=post,
            notification_type="mention"
        )

通知触发的挂载逻辑

不需要引入复杂的信号、中间件机制,直接在帖子保存的流程里调用辅助函数即可,逻辑直观、调试方便,完全适配简易应用的开发需求。比如在发布帖子的视图里:

# posts/views.py 发布帖子的视图片段
def publish_post(request):
    if request.method == "POST":
        form = PostForm(request.POST)
        if form.is_valid():
            post = form.save(commit=False)
            post.author = request.user
            post.save()
            # 帖子保存成功后调用函数生成提及通知
            from notifications.utils import create_mention_notifications
            create_mention_notifications(post)
            return redirect("post_detail", post_id=post.id)

用户后续编辑帖子的时候,也可以在帖子保存的位置再次调用这个函数,因为函数本身已经做了去重判断,不会产生重复通知。

通知页面视图实现

完全匹配需求:展示当前用户收到的所有通知、统计未读数量、用户访问页面后自动将所有通知标记为已读,参考实现:

# notifications/views.py
from django.shortcuts import render
from .models import Notification

def notification_list(request):
    # 获取当前登录用户收到的全部通知
    user_notifications = Notification.objects.filter(recipient=request.user)
    # 先统计访问前的未读数量,避免标记已读后未读数为0的问题
    unread_count = user_notifications.filter(is_read=False).count()
    # 批量把未读通知标记为已读
    user_notifications.filter(is_read=False).update(is_read=True)
    return render(request, "notifications/notification_list.html", {
        "notifications": user_notifications,
        "unread_count": unread_count
    })

落地注意事项

  • 如果项目自定义的用户名规则支持中文、特殊字符,可以直接调整正则的匹配范围,不要硬套默认规则
  • 如果担心匹配到内容里的非提及场景(比如代码块里的@、邮箱地址),可以先过滤掉这部分内容再做匹配,简易应用初期可以先不做这个优化
  • 模板里渲染未读数量的时候,直接使用视图传过来的unread_count变量即可,不要在模板里重复查询数据库

内容的提问来源于stack exchange,提问作者Santiago

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.01 04:06:04