如何创建一个为模型创建信号的 Django 装饰器?

问题描述 投票:0回答:1

我想在 Django 中创建一个自定义装饰器,我可以将其放在我的模型上,并且它使用我的业务逻辑创建一个信号。每个信号的逻辑都是相同的,唯一改变的是它所附加的模型。我无法理解如何实现这一点。

给定一个模型,例如:

class Post(models.Model):
    company = models.ForeignKey(Company, on_delete=models.CASCADE)
    title = models.CharField(max_length=100)

理想情况下,我希望装饰器具有将其放在我的模型上的功能,例如:

@custom_signal_decorator()
class Post(models.Model):
    company = models.ForeignKey(Company, on_delete=models.CASCADE)
    title = models.CharField(max_length=100)

它会创建一个信号,如下所示:

@receiver(post_save, sender=sender)
def notify_created(sender, instance, created, **kwargs):
    channel_layer = channels.layers.get_channel_layer()
    group_name = f'notifications_{instance.company.id}'
    async_to_sync(channel_layer.group_send)(
        group_name,
        {
            "type": "notify_change",
        }
    )

最终目标是在创建新帖子时向前端发送通知来实时跟踪更改。当为每个模型手动创建信号时,这一切都有效,但我觉得装饰器更有意义,可以放置我们想要跟踪的模型。

任何关于我如何实现这一点的输入都会有帮助,或者您认为不使用装饰器也可以使用的另一种方式。谢谢你。

我尝试自己创建一个自定义装饰器,但我无法弄清楚如何在装饰器内动态发送模型以便它跟踪该模型,这主要是我不明白它是如何工作的。

django django-rest-framework django-channels
1个回答
0
投票

您可以制作一个装饰器,使用传递的模型类来注册信号:

from django.db.models.signals import post_save


def notify_created(sender, instance, created, **kwargs):
    channel_layer = channels.layers.get_channel_layer()
    group_name = f'notifications_{instance.company.id}'
    async_to_sync(channel_layer.group_send)(
        group_name,
        {
            'type': 'notify_change',
        },
    )


def custom_signal_decorator(model):
    post_save.connect(notify_created, sender=model)
    return model

并像这样使用它:

@custom_signal_decorator
class Post(models.Model):
    company = models.ForeignKey(Company, on_delete=models.CASCADE)
    title = models.CharField(max_length=100)
© www.soinside.com 2019 - 2024. All rights reserved.