Django信号:如何从实例获取ManyToManyRel关联对象的ID
解决Django多对多关联对象ID获取问题
你当前代码中拿到的ManyToManyRel是模型间的关系定义,并非实例的关联数据。要获取与Document实例关联的SrdRevision对象ID,无需遍历模型字段,直接通过实例的关联属性操作即可。
具体修改方案
- 确认
Document模型中关联SrdRevision的字段名(对应你代码里的srd_revision/srdrevision/srd_rev其中一个) - 通过实例的关联属性获取所有关联对象,再提取ID
修改后的代码片段示例:
@receiver(post_save, sender=Document) def handle_added_or_edited_element(sender, instance, **kwargs): ''' This signal is used to compare the original and the current instance of the object being saved. If at least one field has changed, a row is inserted in the revision history of the related srd_revision ''' # 定义可能的关联字段名列表 related_fields = ['srd_revision', 'srdrevision', 'srd_rev'] # 遍历字段名,找到实例上存在的有效关联字段 for field_name in related_fields: if hasattr(instance, field_name): # 获取关联的所有SrdRevision对象 related_revisions = getattr(instance, field_name).all() # 提取每个关联对象的ID revision_ids = [rev.id for rev in related_revisions] # 可根据需求使用这些ID,比如打印或存入历史记录 print(revision_ids) break # 找到有效字段后停止遍历 # 保留你原有的字段变更检查逻辑 for field in sender._meta.get_fields(): if not isinstance(field, (models.ManyToOneRel, models.ManyToManyRel)): if instance._get_field_value_map(instance._meta)[field.name].value != instance.__original_instance._get_field_value_map(instance._meta)[field.name].value: chapter, message = RevisionHistory().get_document_messages(instance=instance, created=False, updated_field=field.name) # 注意:创建SrdRevisionHistory后需调用save()才能写入数据库 SrdRevisionHistory(chapter=chapter, title=message).save()
关键说明
getattr(instance, field_name):通过字段名动态获取实例的关联管理器.all():获取多对多关系中所有关联的对象(如果是一对一/外键关系,可改用.first()或直接访问属性)- 原代码中创建
SrdRevisionHistory后未调用save(),这会导致数据无法存入数据库,建议补充该操作
内容的提问来源于stack exchange,提问作者Atro_TLT
相关产品推荐
相关产品推荐

