我想在Django中创建一个可以放在我的模型上的定制decorator ,它会用我的业务逻辑创建一个信号.每个信号的逻辑都是相同的,唯一变化的是它所连接的模型.我很难理解如何做到这一点.

给定一个模型,例如:

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",
        }
    )

最终目标是通过在创建新帖子时向前端发送通知来实时跟踪更改.当手动 for each 模型创建一个信号时,这一切都有效,但我觉得装饰者会更有意义,把我们想要跟踪的模型放在上面.

我将如何实现它的任何类型的输入都将是有帮助的,或者是另一种您认为可能在不使用decorator 的情况下工作得很好的方式.谢谢.

我试着自己创建一个定制的decorator ,但我不知道如何动态地将模型发送到decorator 内部,以便它跟踪该模型,这主要是我不理解它如何工作的地方.

推荐答案

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

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)

我们可以判断模型是否包含company_id字段,从而防止将decorator 添加到与信号不兼容的模型中:

def custom_signal_decorator(model):
    model._meta.get_field('company_id')
    post_save.connect(notify_created, sender=model)
    return model

Note:用company_id代替company.id,可以提高查询关联对象主键的性能.这将直接访问模型中存储的值,从而节省了到数据库的额外往返行程.

Django相关问答推荐

Django Prefetch上的多重过滤

如何在Django模板中有条件地传递值给with变量?

为什么 timezone.now 在作为默认值应用于 Django 中的 DateField 时显示future 日期

基于每个条目的 Django Queryset 过滤

Django RESTful API - django-piston vs. django-tastypie

如何从 django 模板生成静态 html 文件?

Django 管理命令参数

如何在 Django 中返回静态 HTML 文件作为响应?

magic有什么问题?

django npm 和 node 包架构

如何使用 select_for_update 在 Django 中获取查询?

在 Django 应用程序之间共享模型

如何使 Django QuerySet 批量删除()更高效

django 模板列表变量中的最后一个元素

更改 Django ModelChoiceField 以显示用户的全名而不是用户名

'function' 对象没有属性 'as_view'

如何在 django 中使用更少的 css?

如何在 Django 中更改上传文件的文件名?

使用 .order_by() 和 .latest() 的 Django 查询

防止 django 管理员转义 html