有示例模型:
class MyModel(models.Model):
name = models.CharField()
version = models.IntegerField()
我需要根据具有相同名称的实例的最高版本来设置version
字段值。为此,我重写了save
方法:
def save(self, *args, **kwargs):
max_version = MyModel.objects \
.filter(name=self.name) \
.aggregate(max_version=Max('version'))['max_version'] or 0
self.version = max_version + 1
super(MyModel, self).save(*args, **kwargs)
如何在这里避免比赛情况?
编辑:版本必须唯一(在具有相同名称的实例之间),但顺序不是太重要。
答案 0 :(得分:0)
我认为一个简单的原子transaction应该可以解决您的问题。
from django.db import transaction
def save(self, *args, **kwargs):
with transaction.atomic():
max_version = MyModel.objects \
.filter(name=self.name) \
.aggregate(max_version=Max('version'))['max_version'] or 0
self.version = max_version + 1
super(MyModel, self).save(*args, **kwargs)
尽管超出实际问题的范围,您可能只想在创建记录时才更新version
字段(首次保存)。您可以通过验证pk
是None
来做到这一点。
from django.db import transaction
def save(self, *args, **kwargs):
if self.pk is None:
with transaction.atomic():
max_version = MyModel.objects \
.filter(name=self.name) \
.aggregate(max_version=Max('version'))['max_version'] or 0
self.version = max_version + 1
super(MyModel, self).save(*args, **kwargs)
else:
super(MyModel, self).save(*args, **kwargs)