我有一個簡單class
模型Django管理(V 1.9.2。)是這樣的:save()方法提交異步更改?
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)
還有的問題。雖然我在save()
方法內改變bar
的值,但在我調用異步方法之前,當觸發process_new_users()
方法時,instance.bar
仍爲None
(初始值)。
我不確定這是因爲save()
方法異步提交更改,並且當觸發process_new_users()
時,它尚未提交更改並正在檢索舊值,或者如果我缺少其他內容。
我的假設是否正確?如果是的話,有沒有辦法強制save()
中的值同步提交,所以我可以,然後調用異步方法?
注意:實現此目的的任何替代方法也是受歡迎的。
更新1:作爲@格特的答案,我實現了一個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
信號。
'save()'方法不會異步提交更改。在模型(同步)保存之前,您正在調用異步任務,因此在模型實際保存後它可能運行也可能不運行。 – knbk
@knbk任何方式我可以在save()方法成功保存模型更改後運行異步任務嗎? (不知道這裏是否有'save()'的*後保存*鉤子...) – nKn