美文网首页
[Django] 多对多Many-to-Many 字段的特殊处理

[Django] 多对多Many-to-Many 字段的特殊处理

作者: alue | 来源:发表于2022-04-27 22:02 被阅读0次

在处理M2M字段时,很多人会遇到这样一个坑。

例如,我们打算在对象修改时,触发一些动作。常规的做法就是重载模型的 save() 方法。

举例说明, ElectricStatus 模型中有个devices的多对多字段。
我们patch了数据

{
    "devices": [
    17
    ]
}

但在 ElectricStatus 模型的 save() 方法中,self.devices.all() 并没有17,即便是重新获取

def save(self, *args, **kwargs):
    super().save(*args, **kwargs)
    new_instance = ElectricStatus.objects.get(pk=self.pk)  
    # 仍然没有17的存在
    print(new_instance.devices.all())

看来,Django在保存模型时,还没有开始更新m2m字段。所以,用 save() 方法是不可行的。

仔细想想也对,m2m字段其实暗含了另一个隐藏模型,它在这里对应的是electricstatus_devices表。如果 ElectricStatus 的对象还没有保存,那么electricstatus_devices并不会知道这个对象的id,根本无法完成更新。

所以,Django只能先保存ElectricStatus 的对象,然后再更新electricstatus_devices表。这就能解释前面的疑惑了。

为了实现一开始的需求,Django提供了m2m_changed信号,也就是在electricstatus_devices模型变动时,能够触发这个信号,让我们有机会去hook一些动作。

如果用的是django admin,那么可以用save_related来hook;如果用的是 django restframework,还可以用重载 perform_update方法来hook。

相关文章

  • [Django] 多对多Many-to-Many 字段的特殊处理

    在处理M2M字段时,很多人会遇到这样一个坑。 例如,我们打算在对象修改时,触发一些动作。常规的做法就是重载模型的 ...

  • vs上的多对多关系的修改

    多对多基数关系The many-to-many cardinality relationships have be...

  • Many to Many

    Prisma多对多操作分为隐式(Implicit many-to-many relations)和显式(Expli...

  • Django Model

    django的模型挺好的,不用自己写SQL。外键,多对多,一对多,多对一。 参考:Django Project

  • Django - ORM多对多

    现实生活中多对多的实例有: 这个ManyToManyField可以在两个Class的任何一个都无所谓,在数据库中生...

  • django 多对多模型

    文集和文章之间的关系是一个典型的多对多关系(购物车和商品的关系也是是一样),用关系型数据库可以很好的处理,需要有一...

  • django 第四天2019-07-31

    django 关系型数据库的关系包括三种类型: ForeginKey: 一对多,将字段定义在多的一端中 ManyT...

  • 第五章 Django By Example

    在网站中分享内容 此章内容: 创建一个many-to-many(多对多)关系 定制表单(form)的行为 在 Dj...

  • Mybatis第二天下午

    实体与数据库字段不匹配处理 1、如果字段不相同,则数据封装不上,处理方式如下: 多表连接:(一对一 一对多) ...

  • Django 模型间的关系

    Django模型之间的关系 Django模型的对应关系,一对一,一对多,以及多对多的关系。 一对一 OneToOn...

网友评论

      本文标题:[Django] 多对多Many-to-Many 字段的特殊处理

      本文链接:https://www.haomeiwen.com/subject/dtolyrtx.html