Обновление модели при удалении объекта, на который она ссылается через отношение ManyToMany
Например, у меня есть модель
class ModelA(models.Model):
name = models.CharField()
class ModelB(models.Model):
last_modified_time = models.DateTimeField()
as = models.ManyToManyField('ModelA')
когда я удаляю экземпляр ModelA, я хотел бы также обновить поле last_modified_time во всех экземплярах ModelB, которые ссылались на ModelA. Для этого я могу использовать сигнал predelete, т. е.
.def pre_delete_handler(sender=None, instance=None, *args, **kwargs):
# update all using instance.modelbs...
models.signals.pre_delete.connect(pre_delete_handler, sender=ModelA)
но тогда каждый раз, когда новая модель ссылается на нее через ManyToMany, этот фрагмент кода нужно обновлять, что не очень удобно с точки зрения обслуживания. Я ищу способ перечислить все модели, на которые ссылается ModelA, чтобы можно было выполнить одно обновление, которое охватывает все случаи, но не могу найти лучший способ сделать это. Каков правильный способ перечисления всех объектов, на которые ссылается ModelA?
Если все модели, которые ссылаются на A
как многие ко многим, имеют поле last_modified_time
, то может работать что-то вроде этого:
from django.db.models.fields.reverse_related import ManyToManyRel
from django.utils import timezone
def pre_delete_handler(sender=None, instance=None, *args, **kwargs):
if not instance:
return
# Get all reverse m2m fields
reverse_m2m_fields = [m for m in instance._meta.model._meta.get_fields() if isinstance(m, ManyToManyRel)]
# or [m for m in ModelA._meta.get_fields() if isinstance(m, ManyToManyRel)]
for f in reverse_m2m_fields:
# Find the name of the reverse m2m field from this model
field_name = f.related_name or f.related_query_name or f'{f.name}_set'
getattr(instance, field_name).update(last_modified_time=timezone.now())
models.signals.pre_delete.connect(pre_delete_handler, sender=ModelA)