我有一个带有自定义save()方法的模型,如果条件匹配,则创建中间模型:
class Person(models.Model):
integervalue = models.PositiveIntegerField(...)
some_field = models.CharField(...)
related_objects = models.ManyToManyField('OtherModel', through='IntermediaryModel')
...
def save(self, *args, **kwargs):
if self.pk is None: # if a new object is being created - then
super(Person, self).save(*args, **kwargs) # save instance first to obtain PK for later
if self.some_field == 'Foo':
for otherModelInstance in OtherModel.objects.all(): # creates instances of intermediate model objects for all OtherModels
new_Intermediary_Model_instance = IntermediaryModel.objects.create(person = self, other = otherModelInstance)
super(Person, self).save(*args, **kwargs) #should be called upon exiting the cycle
但是,如果通过shell和管理界面编辑现有的人员 - 如果我更改某些现有人员的整数值 - 则不会保存更改。好像由于某种原因最后超级(...)。没有调用save()。
但是,如果我要将else块添加到外部if,例如:
if self.pk is None:
...
else:
super(Person, self).save(*args, **kwargs)
save()将按预期对现有对象起作用 - 更改后的整数值将保存在数据库中。
我错过了什么,或者这是正确的行为?是" self.pk是无"确实是在Django中创建对象的有效指示器吗?
P.S。我目前正在将其重写为信号,但这种行为仍然让我感到困惑。
答案 0 :(得分:1)
如果您的pk is None
,超级save()
被调用两次,我认为这不是您所期望的。尝试这些更改:
class Person(models.Model):
def save(self, *args, **kwargs):
is_created = True if not self.pk else False
super(Person, self).save(*args, **kwargs)
if is_created and self.some_field == 'Foo':
for otherModelInstance in OtherModel.objects.all():
new_Intermediary_Model_instance = IntermediaryModel.objects.create(person = self, other = otherModelInstance)
答案 1 :(得分:0)
覆盖save()
方法并不是一个好主意。 Django正在幕后做很多事情,以确保模型对象按预期保存。如果你做得不对,就会产生奇怪的行为并且难以调试。
请检查django signals,这是访问模型对象信息和状态的便捷方式。它们提供有用的参数,例如instance
,created
和updated_fields
,以满足您检查对象的需要。
答案 2 :(得分:0)
感谢大家的回答 - 仔细检查后,我可以得出结论,我绊倒了自己的双脚。
经过仔细检查甚至与pdb一起旅行后,我发现原始代码在最后一个super()之前混合了缩进 - \ t而不是\ s {4}。save()。