У меня есть модель 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()
).
Кроме того, я хотел бы сделать обязательные аргументы field
и slug_field
, но я не совсем понимаю, как это будет работать, потому что обработчики, похоже, ожидают фиксированный набор аргументов, описанный в https://docs.djangoproject.com/en/2.0/ref/signals/#pre-save.
Как я могу реализовать этот приемник «расширяемым» способом?
Обновление
Из определения .connect()
может показаться, что он принимает необязательный аргумент sender
, но когда я адаптирую приведенный выше пример к
pre_save.connect(
sender=SessionType,
receiver=partial(create_slug_field, field='title', slug_field='smattering_slug'))
и установить трассировку в функции create_slug_field
, трассировка не приводит к тому, что Python попадает в отладчик, то есть функция не вызывается! Как в этом случае моя «обобщенная» версия не эквивалентна исходной версии?