В Django, как я могу уведомить родителя, когда ребенок сохранен в отношении внешнего ключа?

У меня есть две следующие модели:

class Activity(models.Model):
    name = models.CharField(max_length=50, help_text='Some help.')
    entity = models.ForeignKey(CancellationEntity)
    ...


class Cancellation(models.Model):
    activity = models.ForeignKey(Activity)
    date = models.DateField(default=datetime.now().date())
    description = models.CharField(max_length=250)
    ...

Я хотел бы, чтобы модель Activity была осведомлена о том, что аннулирование, связанное с ней, сохраняется (как вставлено, так и обновлено).

Каков наилучший способ сделать это?

Ответы

Ответ 1

То, что вы хотите посмотреть, это сигналы Django (проверьте this страница), в частности, сигналы модели - точнее, сигнал post_save. Сигналы - версия Django для системы плагинов/крюков. Сигнал post_save отправляется каждый раз, когда модель сохраняется, обновляется или создается (и она сообщит вам, была ли она создана). Вот как вы будете использовать сигналы для получения уведомления, если у Activity есть аннулирование

from django.db.models.signals import post_save

class Activity(models.Model):
    name = models.CharField(max_length=50, help_text='Some help.')
    entity = models.ForeignKey(CancellationEntity)

    @classmethod
    def cancellation_occurred (sender, instance, created, raw):
        # grab the current instance of Activity
        self = instance.activity_set.all()[0]
        # do something
    ...


class Cancellation(models.Model):
    activity = models.ForeignKey(Activity)
    date = models.DateField(default=datetime.now().date())
    description = models.CharField(max_length=250)
    ...

post_save.connect(Activity.cancellation_occurred, sender=Cancellation)

Ответ 2

Что случилось со следующим?

class Cancellation( models.Model ):
    blah
    blah
    def save( self, **kw ):
        for a in self.activity_set.all():
            a.somethingChanged( self )
        super( Cancellation, self ).save( **kw )

Это позволит вам точно контролировать уведомление среди моделей. В некотором смысле, это канонический "Почему OO так хорошо?" вопрос. Я думаю, что OO хорош именно потому, что ваша коллекция объектов Cancellation and Activity может полностью сотрудничать.