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

如何在Django中实现游戏/电影模型创建时自动通知用户

实现新游戏/电影发布时自动发送通知的方案

第一步:修正模型结构

你当前的Movies模型嵌套在Games类中,这是错误写法,先调整为独立模型:

# games model
GAME_TYPE=(
    ("action", "action"),
    ("adventure", "adventure"),
    ("racing", "racing"),
    ("puzzle", "puzzle"),
)
MOV_TYPE=(
    ("action", "action"),
    ("adventure", "adventure"),
    ("sci-fi", "sci-fi"),
    ("horror", "horror"),
    ("drama", "drama"),
)
GAME_OS=(
    ("Windows", "Windows"),
    ("Android", "Android"),
)

class Games(models.Model):
    name=models.CharField(max_length=50)
    type=models.CharField(max_length=40, choices=GAME_TYPE)
    os=models.CharField(max_length=15, choices=GAME_OS)
    img=models.ImageField()
    developer=models.CharField(max_length=50)
    version=models.CharField(max_length=10)
    ratings=models.CharField(max_length=10)
    description=models.TextField()

    def __str__(self) -> str:
        return self.name

class Movies(models.Model):
    name=models.CharField(max_length=50)
    type=models.CharField(max_length=40, choices=MOV_TYPE)
    description=models.TextField()
    released=models.DateField()

    def __str__(self) -> str:
        return self.name

第二步:创建通知模型(存储站内通知)

如果需要实现站内通知,先创建Notification模型记录通知内容与状态:

from django.conf import settings
from django.db import models

class Notification(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True, blank=True)
    CONTENT_TYPE_CHOICES = (
        ("game", "新游戏"),
        ("movie", "新电影"),
    )
    content_type = models.CharField(max_length=10, choices=CONTENT_TYPE_CHOICES)
    content_id = models.IntegerField()  # 关联对应的游戏/电影ID
    message = models.TextField()
    is_read = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f"{self.user.username if self.user else '全体用户'}: {self.message[:20]}"

第三步:用Django信号触发通知逻辑

利用Django的post_save信号,在新增游戏/电影时自动执行通知生成逻辑:

1. 编写信号处理函数

在你的app目录下新建signals.py,添加以下代码:

from django.db.models.signals import post_save
from django.dispatch import receiver
from django.conf import settings
from .models import Games, Movies, Notification

@receiver(post_save, sender=Games)
def send_new_game_notification(sender, instance, created, **kwargs):
    if created:  # 仅在新增数据时触发
        message = f"新游戏上线:{instance.name},类型:{instance.get_type_display()},支持平台:{instance.get_os_display()}"
        # 给所有用户发送站内通知
        users = settings.AUTH_USER_MODEL.objects.all()
        for user in users:
            Notification.objects.create(
                user=user,
                content_type="game",
                content_id=instance.id,
                message=message
            )
        # 可选:添加邮件通知
        # from django.core.mail import send_mail
        # send_mail(
        #     subject="新游戏上线通知",
        #     message=message,
        #     from_email=settings.DEFAULT_FROM_EMAIL,
        #     recipient_list=[user.email for user in users],
        #     fail_silently=False,
        # )

@receiver(post_save, sender=Movies)
def send_new_movie_notification(sender, instance, created, **kwargs):
    if created:
        message = f"新电影发布:{instance.name},类型:{instance.get_type_display()},上映日期:{instance.released.strftime('%Y-%m-%d')}"
        users = settings.AUTH_USER_MODEL.objects.all()
        for user in users:
            Notification.objects.create(
                user=user,
                content_type="movie",
                content_id=instance.id,
                message=message
            )
        # 可选:添加邮件通知
        # from django.core.mail import send_mail
        # send_mail(
        #     subject="新电影发布通知",
        #     message=message,
        #     from_email=settings.DEFAULT_FROM_EMAIL,
        #     recipient_list=[user.email for user in users],
        #     fail_silently=False,
        # )

2. 注册信号

修改app目录下的apps.py,确保Django启动时加载信号:

from django.apps import AppConfig

class YourAppNameConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'your_app_name'  # 替换成你的app名称

    def ready(self):
        import your_app_name.signals  # 替换成你的app名称

第四步:前端展示通知(可选)

在用户中心页面查询并展示该用户的未读通知:

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

def user_notifications(request):
    notifications = Notification.objects.filter(user=request.user, is_read=False).order_by('-created_at')
    # 可选:标记所有未读通知为已读
    # notifications.update(is_read=True)
    return render(request, 'notifications.html', {'notifications': notifications})

可选:添加用户订阅功能

如果不想给所有用户发通知,可新增订阅模型,让用户选择订阅的游戏/电影类型:

class UserSubscription(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    subscribed_game_types = models.CharField(max_length=200, blank=True)  # 用逗号分隔类型,如"action,adventure"
    subscribed_movie_types = models.CharField(max_length=200, blank=True)

    def __str__(self):
        return f"{self.user.username}的订阅"

然后修改信号处理函数,仅给订阅对应类型的用户发通知:

@receiver(post_save, sender=Games)
def send_new_game_notification(sender, instance, created, **kwargs):
    if created:
        message = f"新游戏上线:{instance.name},类型:{instance.get_type_display()},支持平台:{instance.get_os_display()}"
        # 过滤订阅了该游戏类型的用户
        subscribed_users = settings.AUTH_USER_MODEL.objects.filter(
            usersubscription__subscribed_game_types__contains=instance.type
        )
        for user in subscribed_users:
            Notification.objects.create(
                user=user,
                content_type="game",
                content_id=instance.id,
                message=message
            )

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 21:00:02