我正在try 自动递增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)

或在Object实例上执行以下操作:

counter, _ = Counter.objects.get_or_create(name=name)
counter.count = F("count") + 1
counter.save(update_fields=["count"])

Remember to specify 100, or you might encounter race conditions on other fields of the model.

官方文件中增加了关于race condition avoided by using F expressions的注释.

Django相关问答推荐

获取PyCharm中继承方法的未解析属性引用

在Django管理中仅显示外键的特定值

django-filter compose 过滤的 url

情节主题更改问题

SQLite上可以正常使用Many2Many链接注释,但MariaDB上无法正常使用(生产环境)

无法迁移,模型中的外键导致了问题

Django中的多对多关系?

Django 身份验证系统修改

"" 需要有字段 "id" 的值才能使用这种多对多关系

django 创建多种类型用户的最佳方法

如何获得用户权限?

在 Bootstrap 中使单击的选项卡处于活动状态

如何测试某个日志(log)消息是否记录在 Django 测试用例中?

如何在 twitter-bootstrap 模式窗口中插入 django 表单?

测试 Django 信号的正确方法

清理提交的表单数据中的 HTML

从表单获取模型实例而不保存

Table doesn't exist表不存在

Django 自定义用户邮箱帐户验证

django.urls.path中name参数的作用是什么?