2016-07-06 4 views
0

Каков наилучший способ инициировать обновление связанных моделей при изменении одного из полей родительской модели? У меня есть этот набор моделей:Обновление связанных моделей по изменению поля модели

class ActivityObject(models.Model): 
    is_deleted = models.BooleanField(default=False) 

class ActivityJob(models.Model): 
    activity_object = models.ForeignKey(
     ActivityObject, 
     related_name='activity_jobs', 
    ) 
    is_deleted = models.BooleanField(default=False) 

так, если я изложу ActivityObject.is_deleted = True на некотором случае все, что я хочу, чтобы все связанные экземпляры ActivityJob также измененного поля is_deleted к True. Заранее спасибо.

ответ

1

Переопределение сохранить() будет работать:

class ActivityObject(models.Model): 
    is_deleted = models.BooleanField(default=False) 

    def save(self, *args, **kwargs): 
     super(ActivityObject, self).save(args, kwargs) 
     if self.is_deleted: 
      for job in self.activity_jobs: 
       job.is_deleted = True 
       job.save() 

Просто угадать здесь, но если реальная цель этого заключается в удалении ActivityJob сек, когда связанные ActivityObject s удаляются, то вы можете просто идти вперед и удалить ActivityObject. Поведение Django по умолчанию приведет к удалению всех подключенных к нему ActivityJob s.

Если вы хотите выполнить какое-либо другое действие при удалении, используйте сигналы Django pre_delete или post_delete, которые вызовут функцию, которую вы определяете до/после удаления объектов указанного вами типа.

EDIT: если вы когда-либо использовать update() на querysets, занимающихся ActivityObject и изменяющимися is_deleted, вы можете убедиться, что вы выполнить соответствующую update() на ActivityJob, или вы можете переопределить ActivityObject «s queryset функциональность как this сделать это произойдет автоматически.

+0

Что делать, если save() никогда не называется? – Brian

+0

@Brian Можете ли вы привести пример, когда таблица базы данных для объекта ActivityObject изменяется без вызова 'save()'? –

+0

@Yash Tewari Я думаю, что это самое подходящее решение в моем случае, thx – Compadre

0

Вы можете использовать сигналы Django 'pre_delete или post_delete. Более подробные сведения и примеры доступны в Django Signals documentation.

+0

И могу ли я обернуть все это с помощью сигналов кухни от @ transaction.atomic decorator? Потому что в верхнем ответе я могу обернуть весь метод 'save' и почувствовать сохранение, если родительский объект будет изменен, а связанные объекты по какой-то причине не будут изменены. – Compadre

+0

Это поможет? http://django-atomic-signals.readthedocs.io/en/latest/ –

+0

Спасибо за этот ответ, и я понимаю, что это решение более гибко во многих отношениях, но оно также намного сложнее, включая внешние зависимости. Если мне когда-либо понадобится такая гибкость, я буду использовать ваш способ решения этой проблемы. Спасибо, что потратили время на ответы :) – Compadre

Смежные вопросы