Python Django模型中的自定义Id
在我的模型中,我需要一个不同于Django给出的默认ID的ID字段。我需要以下格式的身份证:[年份][升序数字] 示例:Python Django模型中的自定义Id,python,django,django-models,Python,Django,Django Models,在我的模型中,我需要一个不同于Django给出的默认ID的ID字段。我需要以下格式的身份证:[年份][升序数字] 示例:2021001,2021002,2021003 ID不可编辑,但模型条目应采用模型中日期时间字段中ID的年份。我不确定我是否使用了一个普通的Django ID,是否还为模型创建了某种附加ID,或者我是否用一个替换了普通的Django ID。这个问题与我之前为一个项目解决的问题非常相似。为此,我所做的只是简单地使用主键的默认id,同时使用一些额外的字段来生成所需的复合标识符 为了
2021001
,2021002
,2021003
ID不可编辑,但模型条目应采用模型中日期时间字段中ID的年份。我不确定我是否使用了一个普通的Django ID,是否还为模型创建了某种附加ID,或者我是否用一个替换了普通的Django ID。这个问题与我之前为一个项目解决的问题非常相似。为此,我所做的只是简单地使用主键的默认id,同时使用一些额外的字段来生成所需的复合标识符 为了确保计数的唯一性和重新启动,我制作了一个模型,该模型(仅根据逻辑,没有实际约束)中只有一行。每当创建需要此标识符的模型的新实例时,该行将在事务中更新,并使用其存储值 实施情况如下:
from django.db import models, transaction
import datetime
class TokenCounter(models.Model):
counter = models.IntegerField(default=0)
last_update = models.DateField(auto_now=True)
@classmethod
def get_new_token(cls):
with transaction.atomic():
token_counter = cls.objects.select_for_update().first()
if token_counter is None:
token_counter = cls.objects.create()
if token_counter.last_update.year != datetime.date.today().year:
token_counter.counter = 0
token_counter.counter += 1
token_counter.save()
return_value = token_counter.counter
return return_value
def save(self, *args, **kwargs):
if self.pk:
self.__class__.objects.exclude(pk=self.pk).delete()
super().save(*args, **kwargs)
接下来,假设您需要在其他模型中使用此选项:
class YourModel(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
yearly_token = models.IntegerField(default=TokenCounter.get_new_token)
@property
def token_number(self):
return '{}{}'.format(self.created_at.year, str(self.yearly_token).zfill(4))
@classmethod
def get_from_token(cls, token):
year = int(token[:4])
yearly_token = int(token[4:])
try:
obj = cls.objects.get(created_at__year=year, yearly_token=yearly_token)
except cls.DoesNotExist:
obj = None
return obj
注意:这可能不是很精确,因为代码是在我非常缺乏经验的时候编写的,可能有很多地方可以改进。例如,您可以在
year\u token
字段中添加一个unique\u For\u year
,以便:
yearly_token = models.IntegerField(default=TokenCounter.get_new_token, unique_for_year='created_at')