2

目前,我在 models.py 中所做的事情:

class Customer(models.Model):
    def save(self, *args, **kwargs):
        if self.cod == '':
            self.cod = "CUST%d" % self.id
        super(Customer, self).save(*args, **kwargs)

一切似乎都运作良好。问题是id AutoField 实际上跳过了一些数字,我得到了这样的场景:

  • CUST1
  • CUST2
  • CUST4
  • CUST5

如您所见,没有 CUST3,AutoField 跳过了它。但是出于财务目的,我需要代码必须是渐进的和密集的。我该怎么做才能实现我的目标?谢谢

编辑:我正在使用 PostgreSQL

4

1 回答 1

1

正如这里所报道的,这似乎是与 DBMS 相关的事情,与避免无间隙序列的并发和性能有关。

所以我已经使用一个辅助模型“Progressive”解决了这个问题,它持有、锁定和递增一行。

# models.py
from django.db import models, transaction

class Counter(models.Model):
    name = models.CharField(max_length=40, unique=True, db_index=True)
    n = models.PositiveIntegerField(default=1)

class Customer(models.Model):
    def save(self, *args, **kwargs): 
        super(Customer, self).save(*args, **kwargs)

        if self.cod == '':
            with transaction.commit_on_success():
                try:
                    counter = Counter.objects.select_for_update().get(name='Customer')
                except Counter.DoesNotExist:
                    counter = Counter.objects.select_for_update().create(name='Customer')
                self.cod = "CUST%d" % counter.n
                counter.n += 1
                counter.save()
            super(Customer, self).save(*args, **kwargs)

请注意,这select_for_update()是锁定行的原因(但请注意使用的 DBMS),直到事务没有终止。

希望这可以帮助

于 2013-07-09T07:58:38.637 回答