Tutorial¶
Migrating from Django Signals¶
Let’s you have models and signals like this:
# events.models.py
class Event(models.Model):
name = models.CharField(max_length=255)
starts_at = models.DateTimeField()
duration = models.DurationField(default=timedelta(hours=1))
@receiver(pre_save, sender=Event)
def event_pre_save(sender, instance, **kwargs):
if not instance.id:
return
old_instance = Event.objects.get(id=instance.id)
if old_instance.starts_at != instance.starts_at or old_instance.duration != instance.duration:
event_tasks.resync_event_calendars.delay(event_id=instance.id)
class Enrollment(models.Model):
PARTICIPANT = 'participant'
SPEETCHER = 'speetcher'
ORGANIZER = 'organizer'
CO_ORGANIZER = 'co_organizer'
ROLE_CHOICES = [
(PARTICIPANT, 'Participant'),
(SPEETCHER, 'Speetcher'),
(ORGANIZER, 'Organizer'),
(CO_ORGANIZER, 'Co-Organizer'),
]
role = models.CharField(ax_length=255, choices=ROLE_CHOICES)
user = models.ForeignKey("users.User", models.CASCADE, related_name="enrollments")
event = models.ForeignKey("events.Event", models.CASCADE, related_name="enrollments")
@receiver(post_delete, sender=Enrollment)
def enrollment_post_save(sender, instance, **kwargs):
event_tasks.remove_enrollment_calendar.delay(enrollment_id=instance.id)
Transforming it to a Watcher:
# events.watchers.py
from django_watchers.mixins import UpdateWatcherMixin, DeleteWatcherMixin
EventWatcher(UpdateWatcherMixin):
@classmethod
def pre_update(cls, target, meta_params):
source = meta_params.get('source')
if source == 'queryset':
operation_params = meta_params.get('operation_params')
resync = 'starts_at' in operation_params or 'duration' in operation_params
else:
old_instance = target.first()
instance = meta_params.get('instance_ref')
resync = old_instance.starts_at != instance.starts_at or old_instance.duration != instance.duration:
if resync:
event_tasks.resync_event_calendars.delay(event_ids=target.values_list('id'))
EnrollmentWatcher(DeleteWatcherMixin):
@classmethod
def post_delete(cls, target):
event_tasks.remove_enrollment_calendar.delay(enrollment_ids=[enrollment.id for enrollment in target])
# events.models.py
from django_watcher.decorators import watched
from .watchers import EventWatcher, EnrollmentWatcher
@watched(EventWatcher)
class Event(models.Model):
name = models.CharField(max_length=255)
starts_at = models.DateTimeField()
duration = models.DurationField(default=timedelta(hours=1))
@watched(EnrollmentWatcher)
class Enrollment(models.Model):
PARTICIPANT = 'participant'
SPEETCHER = 'speetcher'
ORGANIZER = 'organizer'
CO_ORGANIZER = 'co_organizer'
ROLE_CHOICES = [
(PARTICIPANT, 'Participant'),
(SPEETCHER, 'Speetcher'),
(ORGANIZER, 'Organizer'),
(CO_ORGANIZER, 'Co-Organizer'),
]
role = models.CharField(ax_length=255, choices=ROLE_CHOICES)
user = models.ForeignKey("users.User", models.CASCADE, related_name="enrollments")
event = models.ForeignKey("events.Event", models.CASCADE, related_name="enrollments")