后台工作者和覆盖 Django 模型的保存方法
Background workers and overriding save method on Django models
我有一个很长的 运行 过程,它取决于模型字段。
假设我有一个看起来像这样的模型
class Client(models.Model):
input_data = models.CharField(max_length=100)
# The field that will be computed in the background task
computed_data = models.CharField(max_length=100, null=True, blank=True)
我想在每次更新这个模型时触发一个后台任务,但问题是我还需要在后台任务更新实例后调用save方法。
大致是这样的。
def a_long_running_background_task(instance):
input_data = instance.input_data # Reading the model input data
# Updating the output_data field using the input data from the model instance
instance.output_data = input_data.title()
# To make sure the changes apply to the database we need to call the save method
instance.save()
这段代码的问题在于它会导致无限循环,因为我在save方法上调用了后台任务,而我在后台任务中调用了save方法。
我一直收到这个错误
RecursionError: maximum recursion depth exceeded while calling a Python object
在我研究了这个问题之后,我找到了一个解决方案,建议使用 post_save 信号和 created 属性,然后检查实例是否已创建,然后执行任务,如果它只是已更新,我会跳过它,因为这意味着它正在从后台工作人员调用保存。
信号看起来像这样:
@receiver(post_save, sender=Client)
def handle_new_client(sender, instance, created, **kwargs):
if created:
a_long_running_task(instance)
现在的问题是,我想要一个更新的功能,希望后台任务在更新模型的时候触发,但是目前只在创建对象的时候触发。
我有一个解决方案,但我不确定如何实现它或者它是否可行,即将计算字段从输入字段拆分为两个不同的模型。
非常感谢任何帮助。
一种选择是使用 bulk_update 更新后台任务中的实例。此函数不会调用模型的 save
方法,也不会发出任何信号,从而消除了任何递归问题。
我有一个很长的 运行 过程,它取决于模型字段。
假设我有一个看起来像这样的模型
class Client(models.Model):
input_data = models.CharField(max_length=100)
# The field that will be computed in the background task
computed_data = models.CharField(max_length=100, null=True, blank=True)
我想在每次更新这个模型时触发一个后台任务,但问题是我还需要在后台任务更新实例后调用save方法。
大致是这样的。
def a_long_running_background_task(instance):
input_data = instance.input_data # Reading the model input data
# Updating the output_data field using the input data from the model instance
instance.output_data = input_data.title()
# To make sure the changes apply to the database we need to call the save method
instance.save()
这段代码的问题在于它会导致无限循环,因为我在save方法上调用了后台任务,而我在后台任务中调用了save方法。
我一直收到这个错误
RecursionError: maximum recursion depth exceeded while calling a Python object
在我研究了这个问题之后,我找到了一个解决方案,建议使用 post_save 信号和 created 属性,然后检查实例是否已创建,然后执行任务,如果它只是已更新,我会跳过它,因为这意味着它正在从后台工作人员调用保存。
信号看起来像这样:
@receiver(post_save, sender=Client)
def handle_new_client(sender, instance, created, **kwargs):
if created:
a_long_running_task(instance)
现在的问题是,我想要一个更新的功能,希望后台任务在更新模型的时候触发,但是目前只在创建对象的时候触发。
我有一个解决方案,但我不确定如何实现它或者它是否可行,即将计算字段从输入字段拆分为两个不同的模型。
非常感谢任何帮助。
一种选择是使用 bulk_update 更新后台任务中的实例。此函数不会调用模型的 save
方法,也不会发出任何信号,从而消除了任何递归问题。