save()方法是异步提交更改吗?

时间:2016-03-03 11:56:02

标签: django asynchronous django-models celery

我有一个简单的class模型与Django Admin(v.1.9.2)这样:

from django.contrib.auth.models import User

class Foo(models.Model):
    ...
    users = models.ManyToManyField(User)
    bar = None

我也像这样重载了save()方法:

def save(self, *args, **kwargs):
    self.bar = 1

    async_method.delay(...)

    super(Foo, self).save(*args, **kwargs)

此处async_method是对将在Celery上运行的任务的异步调用,它接受users字段并将向其添加一些值。

同时,只要将用户添加到ManyToManyField,我就会根据bar字段的值执行操作。为此,我定义了一个m2m_changed信号:

def process_new_users(sender, instance, **kwargs):
    if kwargs['action'] == 'post_add':
        # Do some stuff
        print instance.bar

m2m_changed.connect(process_new_users, sender=Foo.users.through)

问题出在那里。虽然我在调用异步方法之前更改了bar方法中save()的值,但在触发process_new_users()方法时,instance.bar仍然是None {1}}(初始值)。

我不确定这是否是因为save()方法异步提交更改,并且当process_new_users()被触发时,它还没有提交更改并且正在检索旧值,或者如果我& #39;我遗漏了别的东西。

我的假设是否正确?如果是这样,有没有办法强制同步提交save()中的值,以便然后调用异步方法?

注意:任何可行的方法也是受欢迎的。

更新1 :截至@ Gert的回答,我实现了transaction.on_change()触发器,因此每当保存Foo实例时,我都可以安全地调用异步之后的功能。为此,我实现了这个:

bar = BooleanField(default=False)   # bar has became a BooleanField

def call_async(self):
    async_method.delay(...)

def save(self, *args, **kwargs):
    self.bar = True

    super(Foo, self).save(*args, **kwargs)

    transaction.on_commit(lambda: self.call_async())

不幸的是,这没有任何改变。我应该在None信号中获取False,而不是True我现在正在获得m2m_changed

1 个答案:

答案 0 :(得分:1)

您希望确保您的数据库是最新的。在Django 1.9中,有一个新的transaction.on_commit可以触发芹菜任务。