我有一个模型,例如
class ModelA(models.Model):
name = models.CharField()
class ModelB(models.Model):
last_modified_time = models.DateTimeField()
as = models.ManyToManyField('ModelA')
当我删除一个ModelA实例时,我还想更新所有引用ModelA的ModelB实例上的last_modified_time字段。我可以为此使用预删除信号,即
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)
,但是每次新模型通过manymany引用它时,这段代码都需要更新,从维护的角度来看,这不是最好的。我正在寻找一种方法来枚举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)