【问题标题】:Can I trigger Celery task on table update in Django?我可以在 Django 中的表更新上触发 Celery 任务吗?
【发布时间】:2022-01-26 14:25:27
【问题描述】:

例如,我有一个模型:

class SomeModel(model.Model):
    is_active = BooleanField(default=False)
    ...

is_active变为True时是否可以触发Celery任务?这里最重要的是,无论 is_active 以何种方式更改,无论是通过 shell、管理面板、api 调用等更改,我都需要触发它。 我使用的数据库是 psql。

【问题讨论】:

  • 你可以做到这一点..有警告。 post_save() 信号,自定义模型 save() 方法是一些示例。请注意,批量操作(SomeModel.objects.update() 之类的东西通常会绕过这些方法/信号。

标签: python django postgresql celery


【解决方案1】:

您可以为此使用信号。一个棘手的部分是确定您的字段在此过程中实际发生了变化。在这种情况下,您应该调用 refresh_from_db 来比较 pre_save 中的值。这有点凌乱但有效

会是这样的

@receiver(pre_save, sender=SomeModel)
def access_rule_card_pre_save(sender, instance: SomeModel, *args, **kwargs):
    old = copy.copy(instance).refresh_from_db()
    changed = instance.is_active != old.is_active
    # you can send task here, or save changed to instance._changed and work with it in post_save

另一种方法是使用单独的库,例如 https://github.com/rsinger86/django-lifecycle

在你的情况下,你可以这样创建一个钩子

@hook(AFTER_UPDATE, when="is_active", has_changed=True)
def on_active_change(self):
    # send celery task here

【讨论】:

  • 这个!谢谢!我发现关于这个库的一个棘手的事情是,当你将 LifecycleModelMixin 与你的自定义模型混合时,你应该首先从这个 mixin 继承,比如class MyCustomUser(LifecycleModelMixin, AbstractBaseUser):。花了一些时间,但这正是我想要的。
猜你喜欢
  • 1970-01-01
  • 2019-12-15
  • 2018-03-21
  • 1970-01-01
  • 2019-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多