在Django中,如何创建可重用的接收器函数?

时间:2018-06-29 00:34:17

标签: python django python-decorators django-signals

我有一个模型SessionType,其中有一个字段title,我想创建一个小版本smattering_slug。当前,这是通过以下接收器功能实现的:

from django.db.models.signals import pre_save
from django.dispatch import receiver
from django.utils.text import slugify


@receiver(pre_save, sender=SessionType)
def create_smattering_slug(sender, instance, **kwargs):
    if not instance.smattering_slug:
        instance.smattering_slug = slugify(instance.title)

但是,我也有其他模型,我想针对这些模型做相同的事情,但是要处理的字段名称和处理的字段不同。

为概括起见,我考虑过做类似的事情:

def create_slug_field(sender, instance, **kwargs):
    field = kwargs.pop('field')
    slug_field = kwargs.pop('slug_field')

    if not getattr(instance, slug_field):
        setattr(instance, slug_field, slugify(field))


from functools import partial
pre_save.connect(partial(create_slug_field, field='title', slug_field='smattering_slug'))

但是,以这种方式,我没有像原始示例中那样传递sender=SessionType。 (从https://docs.djangoproject.com/en/2.0/topics/signals/#connecting-to-signals-sent-by-specific-senders开始,我不清楚如何使用.connect()时如何执行此操作)。

此外,我想制作fieldslug_field必需的参数,但是我不太清楚这是如何工作的,因为处理程序似乎期望{{ 3}}。

我该如何以“可扩展”方式实现此接收器?

更新

https://docs.djangoproject.com/en/2.0/ref/signals/#pre-save中,它似乎接受了一个可选的sender参数,但是当我将上面的示例改编为

pre_save.connect(
    sender=SessionType,
    receiver=partial(create_slug_field, field='title', slug_field='smattering_slug'))

并在create_slug_field函数中设置跟踪,该跟踪不会导致Python掉入调试器,这意味着该函数不会被调用!在这种情况下,我的“通用”版本与原始版本不一样吗?

0 个答案:

没有答案