人们在保存模型时如何生成自定义唯一数字?

时间:2015-09-01 16:57:46

标签: python django django-models

在我工作的地方,报价编号的格式为Qyyyymmddnnnn,他们希望我保留语义信息(报价编号对其发布的日期进行编码;对于任何一天发出的第一个报价,nnnn重置为0001, nnnn比当天之前的报价大一个。)当保存新的Quote时,如何让Django生成这样的数字?

我正在思考

class Quote( models.model):

   quotenumber = models.CharField( 
                  max_length=13, unique=True ) # Qyyyymmddnnnn
   created_on = models.DateTimeField( auto_now_add=True)
   # other fields

   # how to auto-fill the quotenumber if we're saving a new quote? Maybe

   def save(self, *args, **kwargs):
      if self.pk is None; # it's a new quote being saved
          prev_quote = Quote.objects.order_by("-quotenumber")[0]
          today=date.today()
          # generate new_quote_number from prev_quote.quotenumber and today's date
          self.quotenumber = new_quote_number

      super(Post, self).save(*args, **kwargs)

我不确定的事情:

是否可以从内部引用Quote类来获取当前最新的引用? (Python问题和Django问题)

最好是一个单独的模型/数据库表只包含一行,其中包含当前的下一个免费4位数字及其有效日期,而不是点击所有发布的所有报价的大表?

正在测试self.pk is None是否正确判断我们是在保存新记录而不是更新现有记录?或者将quotenumber默认为不可能像全零一样,并测试该默认值会更好吗?

1 个答案:

答案 0 :(得分:0)

是的,您可以在其方法中查询Quote模型。为方便起见,您可能希望使用latest

我不会使用单独的表来存储最新的数字,这会增加复杂性。您需要担心的一件事是并发性,以处理可能同时创建两个不同引号的可能性,尝试保存相同的报价编号。您可以使用类似于what someone used for creating slugs的技术。我唯一不同的就是try保存,以确保没有错误。像这样:

def save(self, *args, **kwargs):
    if self.pk is None:
        prev_quote = Quote.objects.latest()
        #logic to generate quote number using date and prev_quote
        self.quotenumber = new_quote_number
        fixed = self.quotenumber[:9]   # Qyyyymmdd component
        n = int(self.quotenumber[9:])  # nnnn component
        for x in itertools.count(n):
            try:
                super(Post, self).save(*args, **kwargs)
            except IntegrityError:
                self.quotenumber = fixed + str(n+1).zfill(4)
            else:
                break
    else:
        super(Post, self).save(*args, **kwargs)