我试图在 Django 中自动增加一个简单的计数器。我的代码如下所示:
from models import Counter
from django.db import transaction
@transaction.commit_on_success
def increment_counter(name):
counter = Counter.objects.get_or_create(name = name)[0]
counter.count += 1
counter.save()
如果我正确理解 Django,这应该将函数包装在事务中并使增量原子化。但它不起作用,并且计数器更新中存在竞争条件。如何使这段代码成为线程安全的?
最佳答案
使用 an F expression :
from django.db.models import F
在 update()
中:
Counter.objects.get_or_create(name=name)
Counter.objects.filter(name=name).update(count=F("count") + 1)
或在对象实例上:
counter, _ = Counter.objects.get_or_create(name=name)
counter.count = F("count") + 1
counter.save(update_fields=["count"])
记得指定 update_fields
,否则你可能会在模型的其他字段上遇到竞争条件。
关于 race condition avoided by using F expressions 的注释已添加到官方文档中。
关于python - django中计数器的原子增量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1598932/