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

2022-01-24 00:00:00 python django save receiver

问题描述

我在数据库中有一系列测试和案例.每当一个测试被废弃时,它就会被标记为结束日期,并且该测试的任何子案例也应该被标记为结束日期.我看到了两种方法来实现这一点:

I have a series of tests and cases in a database. Whenever a test is obsoleted, it gets end dated, and any sub-cases of that test should also be end dated. I see two ways to accomplish this:

1) 修改保存功能以结束日期子案例.
2)创建一个接收器来监听正在保存的测试模型,然后结束它们的子案例的日期.

1) Modify the save function to end date sub-cases.
2) Create a receiver which listens for Test models being saved, and then end dates their sub-cases.

有什么理由使用其他的吗?

Any reason to use one other than the other?

我看到了这个 博客文章建议在检查模型的给定值时使用 save 方法.由于我正在检查 end_date,也许这表明我应该使用自定义保存?

I see this blog post suggests to use the save method whenever you check given values of the model. Since I'm checking the end_date, maybe that suggests I should use a custom save?

Edit2:另外,为了记录,完整的层次结构是 Protocol -> Test -> Case -> Planned_Execution,并且任何时候 end_dated,每个孩子也必须 endDated.我想我最终会为每个人做基本相同的事情.

Edit2: Also, for the record, the full hierarchy is Protocol -> Test -> Case -> Planned_Execution, and anytime one is end_dated, every child must also be endDated. I figure I'll end up doing basically the same thing for each.

Edit3:原来为了判断当前的save()是否是endDating Test的那个,我需要访问旧数据和新数据,所以我使用了自定义保存.这是它的样子:

Edit3: It turns out that in order to tell whether the current save() is the one that is endDating the Test, I need to have access to the old data and the new data, so I used a custom save. Here's what it looks like:

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()


解决方案

我一般使用这个经验法则:

I generally use this rule of thumb:

  • 如果您必须修改数据以使保存不会失败,请覆盖 save()(您实际上没有其他选择).例如,在我正在开发的应用程序中,我有一个模型,其中包含一个包含选项列表的文本字段.这与旧代码交互,并替换了具有相似文本字段但具有不同选项列表的旧模型.旧代码有时会通过我的模型从旧模型中选择一个选项,但选项之间存在 1:1 映射,因此在这种情况下,我可以将选项修改为新模型.在 save() 中这样做是有意义的.
  • 否则,如果无需干预即可进行保存,我一般会使用保存后信号.
  • If you have to modify data so that the save won't fail, then override save() (you don't really have another option). For example, in an app I'm working on, I have a model with a text field that has a list of choices. This interfaces with old code, and replaces an older model that had a similar text field, but with a different list of choices. The old code sometimes passes my model a choice from the older model, but there's a 1:1 mapping between choices, so in such a case I can modify the choice to the new one. Makes sense to do this in save().
  • Otherwise, if the save can proceed without intervention, I generally use a post-save signal.

相关文章