我有一个看起来差不多的模型:
class MyModel(models.Model):
period = models.IntegerField(unique=True)
beta = models.IntegerField()
gamma = models.FloatField()
我需要period
是从1到N的数字,其中N是此模型中的记录数。因此,如果有5条记录,它将有一组整数[1、2、3、4、5],但是如果有人删除了数字4,则应以使数字5变为4的方式进行更新,因此它们将再次连续。
正确的方法是什么?
答案 0 :(得分:1)
重写.delete()和.save()方法以相对于整个查询集使用索引位置更新周期号。周期值可能与实例的实际主键不匹配,但是它将代表基数位置。
class MyModelManager(models.Manager):
def update_periods(self):
for instance in self.all():
instance.period = instance.get_index()
instance.save()
class MyModel(models.Model):
period = models.IntegerField(unique=True)
beta = models.IntegerField()
gamma = models.FloatField()
objects = MyModelManager()
class Meta:
ordering = ('pk',)
def get_index(self):
# Return the index position of this instance with regards to the sorted queryset
return list(MyModel.objects.values_list('pk', flat=True)).index(self.pk) + 1
def delete(self, *args, **kwargs):
super(MyModel, self).delete(*args, **kwargs)
MyModel.objects.update_periods()
def save(self, *args, **kwargs):
if not self.pk:
# Only update new instances
super(MyModel, self).save(*args, **kwargs)
MyModel.objects.update_periods()
else:
super(MyModel, self).save(*args, **kwargs)
您还可以使用信号处理程序来避免覆盖模型方法。这是概念的证明。用这种方式更新所有期间效率不高,需要使用查询集注释或数据库功能(https://docs.djangoproject.com/en/2.1/ref/models/database-functions/)更新为批量更新。