django.db.models 的 signals 通知

,关于signals的介绍可以查看官方文档
本文主要是记录自己使用signals实现消息提醒的基本逻辑.
在models.py文件中代码如下:

from django.contrib.auth.models import User, Group
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
from django.contrib.contenttypes.models import ContentType
from django.db import models


# Create your models here.

# 用户模型
class Userinfo(models.Model):
    username = models.CharField(max_length=10, primary_key=True)
    password = models.CharField(max_length=20, default='123456')
    # 创建后台admin的User对象
    adminuser = models.OneToOneField(User, on_delete=models.PROTECT, blank=True, null=True, editable=False)

    # …… 扩展信息
    class Meta:
        verbose_name_plural = '用户信息'

    def __str__(self):
        return self.username

    # 创建用户时,生成对应的User对象,用来登录,感谢胡玉新胡老师.
    def save(self, *args, **kwargs):
        if self._state.adding:
            if not User.objects.filter(username=self.username).exists():
                self.adminuser = User.objects.create_user(self.username, password='123456')
        super().save(*args, **kwargs)

# 活动模型
class Activity(models.Model):
    user = models.ForeignKey('Userinfo')
    title = models.CharField(max_length=20, primary_key=True, blank=True, null=True)
    content = models.TextField(blank=True, null=True)
    # 用于监听对象,当数据库中此对象被删除,Notification关联对象也会被删除
    notification = GenericRelation('Notification')

    # …… 扩展信息
    class Meta:
        verbose_name_plural = '活动'

    def __str__(self):
        return self.title


# 课程模型
class Course(models.Model):
    user = models.ForeignKey('Userinfo')
    name = models.CharField(max_length=20, primary_key=True, blank=True, null=True)
    introduce = models.TextField(blank=True, null=True)
    notification = GenericRelation('Notification')

    # …… 扩展信息
    class Meta:
        verbose_name_plural = '课程'

    def __str__(self):
        return self.name


class Notification(models.Model):
    # 和用户对象关联,发送不同的用户
    user = models.ForeignKey('Userinfo')
    # 消息已读
    read = models.BooleanField(default=False)
    # 消息类型
    MESSAGE_TYPE = (
        ('活动', '活动'),
        ('课程', '课程'),
    )
    message_type = models.CharField(choices=MESSAGE_TYPE, max_length=10, blank=True, null=True)
    occurrence_time = models.DateField(u'事件发生时间', auto_now_add=True)
    # 事件对象,event对象是通知事件对象,和使用外键的方式一样,可以使用事件信息
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    event = GenericForeignKey('content_type', 'object_id')

    class Meta:
        verbose_name_plural = '消息提醒'

    def __str__(self):
        return u"%s的提醒事件id: %s" % (self.user, self.event)

views.py 中关联逻辑如下:

from django.db.models import signals

from . import models


# Create your views here.
# 生成通知信息
def notification_save(sender, instance, signal, created, *args, **kwargs):
    # 如果是新建
    if created:
        if isinstance(instance, models.Activity):
            event = models.Notification(user=instance.user, event=instance, message_type='活动')
            event.save()
        elif isinstance(instance, models.Course):
            event = models.Notification(user=instance.user, event=instance, message_type='课程')
            event.save()
    else:
        event = models.Notification.objects.get(user=instance.user)
        event.read = True
        event.save()


# 关联监听模型
signals.post_save.connect(notification_save, sender=models.Course)
signals.post_save.connect(notification_save, sender=models.Activity)

以上是实现signals的基本逻辑,当监听模型创建或者删除,都会生成或删除Notification对应的事件实例,比如:

user = models.Userinfo.objects.create(username='zhanghao')
course = models.Course(name='语文', introduce='好好学习天天向上', user=user)
# 当生成Course对象的时候,会同时生成Notification对象,event是生成的Course对象
course.save()
# 当Course对象被删除时,关联的Notification对象也会被删除
course.delete()

以上就是本文的全部内容,只是为了防止忘记,所以写此文章!如有帮到阅读到此文章的您,深感荣幸!

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值