對於連續序列,你真的不能使用數據庫序列。最簡單的解決方案是擁有自己的表格(Model)來保存序列。下面是一些代碼,我用它來做到這一點:
class Sequence(models.Model):
class Meta:
verbose_name = 'Sequence'
permissions = (('view_sequence', 'Can View Sequence'),)
name = models.CharField(max_length=20)
value = models.IntegerField()
def __str__(self):
return 'Sequence %s=%s' % (self.name, self.value)
def __unicode__(self):
return self.__str__()
@classmethod
def set(cls, name, value=None, increment=0):
with transaction.atomic():
seq = cls.objects.select_for_update().filter(name=name).first()
if not seq:
seq = cls(name=name, value=0)
seq.value = increment + (value if value is not None else seq.value)
seq.save()
return seq.value
@classmethod
def get_next(cls, name):
return cls.set(name, increment=1)
爲了得到下一個序列,你將成爲一個關鍵的字符串名稱的序列,例如:
nextnumber = Sequence.get_next('receipt_%d' % company.pk)
由於每家公司都將有一個不同的密鑰,他們將是不同的序列。
如果你在使用這個假設你的收據保存方法,像這樣:
class Receipt(models.Model):
def save(self, *args, **kwargs):
if not self.seq_num:
self.seq_num = Sequence.get_next('receipt_%d' % self.company.pk)
super(Receipt, self).save(*args, **kwargs)
company = models.ForeignKey(Company, null=False, Blank=False)
seq_num = models.IntegerField(blank=True, unique=True)
# etc etc
當你保存收據,如果沒有一個SEQ_NUM,一個將被分配給它。
這裏只有一個問題,即事務代碼的結構方式,如果出現問題,可能會跳過一個數字。爲避免這種情況,請將transaction.atomic()塊移入您的收據save()方法中。