【发布时间】:2021-01-20 09:08:28
【问题描述】:
我在 Django 的 Invoice 模型中有两列:
class Invoice(models.Model):
use_in_migrations = True
year = models.CharField(max_length=16, default='')
index = models.IntegerField(default=0)
我想在数据库中实现这个序列:
...
2020, 134
2020, 135
2021, 1
2021, 2
...
首先我尝试添加
class Meta:
unique_together = [['prefix', 'index']]
因此,我将确保在列中始终获得唯一的行值。 问题在于,对于 PostgreSQL,这会创建以下序列:
...
2020, 134
2020, 135
2021, 136
2021, 137
...
任何解决方案如何在 Django 中解决这个问题? 我正在使用 Django 2.2。
-----编辑-----
在 cmets 之后,我手动重置了第一个 2021 实例的索引,并将此代码添加到模型中:
def save(self, *args, **kwargs):
# try to save the instance so the index is ordered within prefixes (years)
# that means- a new year starts new indexing from 1
saved = False
self.prefix = str(date.today().year)
if self.index == 0:
while not saved:
try:
obj = self.__class__.objects.filter(prefix=self.prefix).last()
if obj is None:
self.index = 1
else:
self.index = obj.index + 1
super().save(*args, **kwargs)
saved = True
except Exception as e:
pass
if not saved:
super().save(*args, **kwargs) # save anyway
这令人惊讶地创建了一个序列
...
2020, 134
2020, 135
2021, 1
2021, 4
2021, 7
...
【问题讨论】:
-
这里没有技巧,你需要重写 save() 方法并检查索引的最大值为你的“年”值并加 1...
-
嗨@BriseBalloches,如果我这样做,unique_together 会发生什么:1. 它采用最新的索引,即他自己的索引 2. 递增到 1 3. super().save(. ..) 也再次递增最后,我得到索引 N、N + 3、N + 6 ... 如果我删除 unique_together,我放弃检查唯一性的可能性,其中竞争条件(两个在同一时间创建的对象的独立实例)可能导致具有相同的前缀/索引值。
-
1.自己的指数怎么样?这是之前创建的实例索引。检查是否 None 然后默认为 0。 2. 增量,到目前为止,它是 (index + 1)。 3. super().save() 如何增加索引?我不认为它是您模型中的任何增量,它是一个简单的 IntegerField。
-
@BriseBalloches 我在帖子中描述了这一点。
-
抱歉,我不明白为什么每次都加 3。如果可以的话,您应该使用调试器来跟踪索引更改,因为 super.save 添加 1 以及获取最后创建的实例索引是没有意义的。
标签: python django database postgresql