Это - approproate, это использует сигналы django в рамках того же приложения

Попытка добавить уведомление по электронной почте к моему приложению самым чистым возможным способом. Когда определенные поля образцового изменения, приложение должно отправить уведомление пользователю. Вот мое старое решение:

from django.contrib.auth import User

class MyModel(models.Model):
    user = models.ForeignKey(User)
    field_a = models.CharField()
    field_b = models.CharField()

    def save(self, *args, **kwargs):
        old = self.__class__.objects.get(pk=self.pk) if self.pk else None
        super(MyModel, self).save(*args, **kwargs)
        if old and old.field_b != self.field_b:
            self.notify("b-changed")
        # Sevelar more events here
        # ...

    def notify(self, event)
        subj, text = self._prepare_notification(event)
        send_mail(subj, body, settings.DEFAULT_FROM_EMAIL, [self.user.email], fail_silently=True)

Это хорошо работало, в то время как у меня были один или два типа уведомления, но после той просто чувствовавшей несправедливости, чтобы иметь так много кода в моем save() метод. Так, я изменил код на основанный на сигнале:

from django.db.models import signals

def remember_old(sender, instance, **kwargs):
    """pre_save hanlder to save clean copy of original record into `old` attribute
    """
    instance.old = None
    if instance.pk:
        try:
            instance.old = sender.objects.get(pk=instance.pk)
        except ObjectDoesNotExist:
            pass

def on_mymodel_save(sender, instance, created, **kwargs):
    old = instance.old
    if old and old.field_b != instance.field_b:
        self.notify("b-changed")
    # Sevelar more events here
    # ...

signals.pre_save.connect(remember_old, sender=MyModel, dispatch_uid="mymodel-remember-old")
signals.post_save.connect(on_mymodel_save, sender=MyModel, dispatch_uid="mymodel-on-save")

Преимущество - то, что я могу разделить обработчики событий на другой модуль, уменьшив размер models.py и я могу позволить/запретить им индивидуально. Оборотная сторона - то, что этим решением является больше кода, и обработчики сигналов разделяются от самой модели, и не знающий читатель может пропустить их в целом. Так, коллеги, Вы думаете, что это стоит того?

8
задан Matthew Rankin 25 October 2011 в 14:35
поделиться

2 ответа

Я думаю, что это хорошая идея. Доклад «Пользовательские сигналы для несвязанного дизайна» из последнего DjangoCon - отличный ресурс о том, что возможно и уместно с сигналами в Django.

4
ответ дан 5 December 2019 в 21:17
поделиться

Я думаю, что использование сигналов здесь - хорошее дизайнерское решение. Уведомление не является частью сохранения, это следствие сохранения. Работа с такими последствиями - причина, по которой Django предоставляет сигналы.

3
ответ дан 5 December 2019 в 21:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: