Django:何时自定义保存与使用后保存信号

27 投票
2 回答
6240 浏览
提问于 2025-04-16 15:21

我在数据库里有一系列的测试和案例。每当一个测试被淘汰时,它会被标记为结束日期,同时这个测试的所有子案例也应该被标记为结束日期。我想到两种方法来实现这个:

1) 修改保存功能,让它在保存时也给子案例加上结束日期。
2) 创建一个接收器,监听测试模型的保存操作,然后给它的子案例加上结束日期。

有没有什么理由让我们选择其中一种方法而不是另一种呢?

补充:我看到这篇博客文章建议在检查模型的某些值时使用保存方法。因为我在检查结束日期,也许这说明我应该使用自定义保存方法?

补充2:另外,顺便说一下,完整的层级关系是协议 -> 测试 -> 案例 -> 计划执行,每当其中一个被标记为结束日期时,所有子项也必须被标记为结束日期。我想我最终会对每个都做类似的处理。

补充3:结果发现,为了判断当前的保存操作是否是为了给测试加上结束日期,我需要访问旧数据和新数据,所以我使用了自定义保存方法。下面是它的样子:

def save(self):
    """Use a custom save to end date any subCases"""
    try:
        orig = Test.objects.get(id=self.id)
        enddated = (not orig.end_date) and self.end_date is not None   
    except:
        enddated = False

    super(Test, self).save()

    if enddated:
        for case in self.case_set.exclude(end_date__isnull=False):
            case.end_date = self.end_date
            case.enddater = self.enddater
            case.save()

2 个回答

16

在我看来,信号是一种让不同模块之间不那么紧密联系的方法。因为你的任务似乎只在一个模块里进行,所以我会建议你自定义保存功能。

30

我通常遵循这个简单的原则:

  • 如果你需要修改数据才能确保保存成功,那就重写 save() 方法(你基本上没有其他选择)。比如,我正在开发的一个应用里,有一个模型包含一个文本字段,里面有一系列选项。这个模型需要和旧代码兼容,替代一个有类似文本字段但选项列表不同的旧模型。旧代码有时会把旧模型的选项传给我的模型,但这些选项之间是1:1对应的,所以在这种情况下,我可以把旧选项修改成新选项。在 save() 方法里这样做是合理的。
  • 否则,如果保存可以顺利进行而不需要干预,我通常会使用一个保存后的信号。

撰写回答