所以我有以下模型:
class Session(models.Model):
sessionid = models.CharField(max_length=10, primary_key=True)
forgepass = models.ForeignKey(ForgeProfile, on_delete=models.CASCADE)
programid = models.ForeignKey(TrainingProgram, on_delete=models.PROTECT)
program_day = models.IntegerField()
hours = models.IntegerField()
session_date = models.DateField(default=timezone.now())
verified = models.BooleanField(default=False)
def save(self, *args, **kwargs):
session_count = Session.objects.all().count()
self.sessionid = 'S' + self.forgepass.forgepass + id_gen(session_count)
super().save(*args, **kwargs)
def __str__(self):
return '{} - {}'.format(self.sessionid, self.session_date)
字符串
当在后端更新现有记录时,将使用新的sessionid和更新的值创建一条新记录,同时保留旧记录。
1条答案
按热度按时间r6vfmomb1#
这是因为你每次都会生成一个新的主键,而主键是Django决定是否创建或更新的方式。
因此,只有在没有生成主键的情况下,才应该分配一个新的id,比如:
字符串
这本身就有一个问题:如果
self.forgepass.forgepass
以某种方式发生了变化,它不会改变主键。但事实上以任何形式格式化主键都不是一个好主意。你应该把主键看作是黑盒对象:可能是
str
或int
,但这是一个技术细节:不格式化它们。如果你想给它分配一个
sessionid
,你可以添加一个(唯一的)额外的字段,但是不要使用主键。另一个问题是,在这里保存一个对象至少需要三个查询:一个是获取项目的数量,一个是获取
self.forgepass
的.forgepass
,最后保存对象。如果你使用**.bulk_create(…)
[Django-doc]进行批量创建,这就更成问题了,因为.save(…)
**[Django-doc]被绕过了,所以请不要在.save()
处理程序中添加逻辑。