I have a model SessionType
with a field title
of which I'd like to create a slugified version, smattering_slug
. Currently, this is implemented with the following receiver function:
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)
I also have other models, however, for which I'd like to do the same thing, but the name of the field to be slugified and the slug field is different.
To generalize this, I considered doing something like this:
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'))
However, in this way, I'm not passing in sender=SessionType
as in the original example. (It is not clear to me from https://docs.djangoproject.com/en/2.0/topics/signals/#connecting-to-signals-sent-by-specific-senders how to do this while using .connect()
).
Also, I would like to make field
and slug_field
required arguments, but I don't quite see how this would work because the handlers seem to expect a fixed set of arguments described in https://docs.djangoproject.com/en/2.0/ref/signals/#pre-save.
How might I implement this receiver in an 'extensible' way?
Update
From the definition of .connect()
, it would appear that it accepts an optional sender
argument, but when I adapt the example above to
pre_save.connect(
sender=SessionType,
receiver=partial(create_slug_field, field='title', slug_field='smattering_slug'))
and set a trace in the create_slug_field
function, the trace doesn't cause Python to drop into the debugger, meaning that the function is not called! How is my 'generalized' version not equivalent to the original version in this case?