【发布时间】:2018-05-25 21:00:54
【问题描述】:
这是我的模型:
class MyModel(BaseModel):
no = models.PositiveIntegerField() # Human-friendly no -> counter that starts from 1 for every type
type = models.ForeignKey(MyModelType)
我在模型的pre_save 信号中设置了no 字段的值:
@receiver(pre_save, sender=MyModel)
def mymodel_pre_save(sender, instance, *args, **kwargs):
if not instance._state.adding:
return
obj_count = MyModel.objects.filter(type=instance.type).count()
instance.no = obj_count + 1
此代码的错误在于它生成具有相同no 编号的不同对象。当多个用户同时创建对象时,可能会发生这种情况。
修复它的最佳方法是什么?在高负载环境下,将模型的.save() 方法移动分配就足够了吗?
解决方案
最终,我实现了@moooeeeep 的解决方案,但将逻辑从post_save 移至模型的save 方法:
class MyModel(BaseModel):
...
def save(self, *args, **kwargs):
adding = self.pk is None
with transaction.atomic():
super().save(*args, **kwargs)
if adding:
# Compute and set `.no`
obj_count = MyModel.objects.filter(type=self.type, id__lte=self.id).count()
self.no = obj_count
self.save(update_fields=['no'])
【问题讨论】:
-
您是否正在尝试做这样的事情? stackoverflow.com/q/21128899/1025391
-
@moooeeeep,不。一个简单的
AutoField字段是行不通的。我需要计数器来计算具有相同type值的记录。
标签: django