在Django中提交事务后运行代码

时间:2009-06-04 12:25:40

标签: django transactions signals commit

在Django中提交事务后,有没有办法运行一些代码?

我需要向rabbitmq服务器发送一些消息以进行离线处理,但是在提交Django事务之前消息会传递给消费者。

我的消息是在模型的post_save信号中发送的。我正在寻找的是一种类似的机制,使用信号或其他东西,它将在提交后执行代码(如果事务失败,则不执行任何操作)。

我没有在Django中找到任何通用方法。你有什么想法吗?

5 个答案:

答案 0 :(得分:10)

更新2 :django-transaction-hooks为merged into Django core并在Django 1.9版本中发布。

更新django-transaction-hooks解决了这个问题。

我不相信有一种干净的方法可以做到这一点;至少我想不出一个。您可以使用monkeypatch django.db.transaction.commit发送自定义信号;不漂亮,但我认为它会起作用。

django-developers mailing list上提出这个用例可能也很有趣。开发人员通常不愿意添加新信号,但是你可能在这里有一个很好的案例(来自核心开发者的反驳可能包括如何解决你的情况的有用建议)。如果你等到1.1出来之后,你更有可能得到答案。

答案 1 :(得分:7)

希望这可以帮助使用Django 1.9或更高版本的用户。由于1.9 on_commit可用。

所以基本上你会这样做:

from django.db import transaction

transaction.on_commit(
    lambda: send_msg_to_rabbitmqp(param1, param2, ...)
)

如果您希望保留post_save,仍然可以使用on_commit

@receiver(pre_save, sender=MyModel)
def my_handler(sender, instance, created, **kwargs):
    transaction.on_commit(
        lambda: send_msg_to_rabbitmqp(instance.id)
    )

答案 2 :(得分:5)

我通过猴子修补django实现了交易信号(post_commitpost_rollback): http://gist.github.com/247844

答案 3 :(得分:1)

一种可能性是将事务中间件子类化,以便它在提交时发送自定义信号。你的代码可以监听那个信号,而不是post_save。

答案 4 :(得分:1)

请查看django-celery-transactions以获得此解决方案。

我最近完成了拆分并将基础信号代码重构为独立应用django-db-signals