假设我有一些包含某些项目的群组。我希望项目在一个组中具有唯一索引:
class Item(models.Model):
group = models.ForeignKey(Group, null=True)
index = models.IntegerField(default=0)
class Meta:
unique_together=('group','index')
def save(self):
if self.pk is None and self.group_id is not None:
self.thread_index = Item.objects.filter(group_id=group_id).count()+1
return super(Item, self).save()
但这是有问题的,因为更新不是原子的,即在我计算thread_index之后和写入数据库之前,另一个事务可能添加了另一行。
我知道我可以使用它来捕获IntegrityError并重试。但我想知道是否有一种很好的方法可以将其作为插入命令的一部分原子填充,其中SQL类似于:
insert into app_item (group, index)
select 25, count(*) from app_item where group_id=25
答案 0 :(得分:0)
由于您使用的是django模型,除非您另行指定,否则添加索引字段会为您提供添加到所有模型的primary key?除非您需要具有顺序索引的项目,这在删除对象时仍然存在问题,否则id字段肯定会满足您概述的要求。
如果您必须拥有此字段,则可以选择使用signals。为对象的post_save信号写一个接收器,可以想象它可以处理它。
答案 1 :(得分:0)
一种可能的解决方案是,如果您遇到信号问题或自定义保存方法,请在运行时通过index
property field
class Item(models.Model):
group = models.ForeignKey(Group, null=True)
def _get_index(self):
"Returns the index of groups"
return Item.objects.filter(group_id=group_id).count()+1
index = property(_get_index)
现在使用index
作为Item
模型的字段。