【问题标题】:Alternatives to Django post_saveDjango post_save 的替代品
【发布时间】:2020-04-22 04:05:06
【问题描述】:

关于 Django 信号的问题,例如post_save:

我的理解是由post_save 信号引起的对象更新会触发对该对象的post_save 的额外调用。更进一步,通过 2 个post_save 信号同步两个模型,在一个模型的对象上调用post_save,然后在另一个模型的对象上调用post_save,然后至少在原始对象上调用post_save。有没有办法在这里禁用递归?

此外,总的来说,这实际上是一种可扩展的模式并得到 Django 社区的认可吗?最近遇到this article 建议覆盖模型保存功能,但似乎 Django 用户也没有积极地看待这种方法。还有其他方法吗?

【问题讨论】:

  • 您能分享您问题中的 2 个 post_save 处理程序吗?
  • 我不知道覆盖模型保存方法的任何问题,如果你这样做,你实际上可以传递一个额外的参数来指示它来自另一个覆盖的保存方法,从而打破循环。当您不想修改模型的源代码(例如第三方库)时,信号很有用。
  • 嗯,不知道共享函数代码是不是一个可行的选择,这就是为什么我想在高层询问(对此我深表歉意)。使用理论上定义不明确的 Airbnb 数据库来模糊模型本身,该数据库有一个 Traveler 模型和一个 Booking 模型,两者都带有 first_namelast_name。假设由于某种原因,您希望启用对暂定预订的first_namelast_name 的编辑(已完成的预订,即过去的旅行不受影响)并与旅行者的first_namelast_name 同步,我已经在模型上创建了两个 post_save 函数来保存另一个。
  • 很高兴知道@Selcuk。回顾过去,不鼓励覆盖模型保存方法的少数实例类似于该站点的论点:“可以完成覆盖 save() 方法,但通常不推荐,因为信号/接收器是为特定情况设计的。”我想反对方法 A 的论点只是 b/c 方法 B 存在不是一个强有力的论点。
  • @BobbyMoogs 您是否想要在第一个处理程序更新相关模型时调用另一个 post_save 处理程序?您可以在查询集上使用更新方法来跳过信号处理程序Model.objects.filter(pk=pk).update(foo=bar)

标签: django django-models


【解决方案1】:

我不知道您在哪里找到了这样的断言,即覆盖 Model.save 将是“不鼓励的”并且“信号是为特定情况设计的”,但这完全是无意义的。关于第一点,refer to the official documentation:

还有一组模型方法封装了一堆您想要自定义的数据库行为。特别是您经常希望更改 save() 和 delete() 的工作方式

您可以随意覆盖这些方法(以及任何其他模型方法)来改变行为。

覆盖内置方法的经典用例是,如果您希望在保存对象时发生某些事情

再清楚不过了,覆盖save() 是官方推荐的(并且显而易见的)事情。

现在关于信号,这里再次the official documentation is quite clear

Django 包含一个“信号调度器”,当框架中其他地方发生动作时,它有助于解耦的应用程序得到通知。

IOW,信号旨在帮助编写良好解耦(并且可能可重用)的应用程序 - 而不是向您的 自己的 模型添加自定义行为(这没有任何意义 - 您拥有模型,那么当您可以覆盖模型的方法时,为什么还要使用任何间接级别呢?)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-19
    • 2014-11-12
    • 2011-09-18
    • 2012-12-09
    • 1970-01-01
    • 2020-09-02
    • 1970-01-01
    • 2021-04-10
    相关资源
    最近更新 更多