Django:在内联模型中使用信号

2024-04-20 04:17:08 发布

您现在位置:Python中文网/ 问答频道 /正文

使用Django 2.2

我有两个模型,JobOperation,其中OperationJob有外键关系(即,一个作业可以有0个或多个操作)。你知道吗

我希望人们通过Django管理界面,使用inlines,一起输入关于作业和操作的信息。(这意味着在管理站点上的作业创建/编辑页面上,用户可以添加一个或多个“内联”操作,而无需离开该页面。)

Job有几个字段是从它的相关操作计算出来的。与其简单地让它们成为计算的@property属性,不如让它们成为常规的数据库字段,当操作通过信号改变时,这些字段会得到更新。它看起来像这样:

class Job(models.Model):
    name = models.CharFields(...)

    def compute_fields(self):
        qs = self.operations.filter(...)  # get data from operations
        self.name = ...  # set properties using that data
        self.save()
    ...


class Operation(models.Model):
    job = models.ForeignKey(Job, related_name="operations", on_delete=models.CASCADE)
    ...


@receiver(post_save, sender=Operation)
def update_job_on_operation_save(sender, instance, **kwargs):
    """Update job fields when an operation is saved"""
    instance.job.compute_fields()

问题是:如果有人在Django Admin上编辑Job表单,并且在点击save之前添加了多个内联操作,那么receiver函数会同时被调用多次。我有点担心竞争条件,以及导致Job重新计算某些属性并保存到数据库的每个信号的低效性。你知道吗

最好是将接收器附加到Job,这样函数只被调用一次,但是如果有人在Job表单之外编辑一个Operation,它也会触发重新计算。你知道吗

是否可以为JobOperation设置类似的post_save接收器,并说“如果操作作为作业表单的一部分进行了内联编辑,则忽略操作接收器”?有其他的解决办法吗?你知道吗


Tags: djangonameself编辑表单fieldsmodelssave