25

有什么方法可以在 Django 中的事务提交后运行一些代码?

我需要将一些消息发送到rabbitmq 服务器进行离线处理,但消息在Django 事务提交之前到达消费者。

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

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

4

5 回答 5

21

django-transaction-hooks为 Django < 1.9 解决了这个问题,并且该功能内置于 Django 1.9+ 中

from django.db import transaction

def do_something():
    pass  # send a mail, invalidate a cache, fire off a Celery task, etc.

transaction.on_commit(do_something)
于 2009-06-04T15:13:00.910 回答
14

希望这可以帮助使用 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)
    )
于 2016-01-12T12:06:18.153 回答
5

我已经通过猴子修补 django 实现了事务信号(post_commit和):http: //gist.github.com/247844post_rollback

于 2009-12-03T03:15:34.360 回答
1

一种可能性是对事务中间件进行子类化,以便它在提交时发送自定义信号。您的代码可以侦听该信号,而不是 post_save。

于 2009-06-04T13:19:48.800 回答
1

看看django-celery-transactions来解决这个问题。

我最近完成了将底层信号代码代码拆分并重构为独立应用程序django-db-signals 的工作。

于 2012-12-24T06:32:53.263 回答