在我工作的地方,报价编号的格式为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默认为不可能像全零一样,并测试该默认值会更好吗?
答案 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)