0

假设我有一些包含一些项目的组。我希望项目在组中具有唯一索引:

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
4

2 回答 2

0

Since you're using django models, what does adding an index field give you over the primary key added to all models unless you specify otherwise? Unless you need items to have sequential indices, which would still be problematic upon deleting objects, the id field would certainly appear to satisfy the requirement as you outlined it.

If you have to have this field, then an option could be to take advantage of signals. Write a receiver for the object's post_save signal and it could conceivably handle it.

于 2012-07-27T00:22:24.917 回答
0

一种可能的解决方案是,如果您对信号或自定义保存方法有疑问,请在运行时通过创建index一个属性字段来计算它

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

于 2012-07-27T06:46:46.410 回答