重写的save()方法行为不使用super()。save()方法

时间:2016-01-15 18:19:58

标签: django django-models

我有一个带有自定义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。我目前正在将其重写为信号,但这种行为仍然让我感到困惑。

3 个答案:

答案 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,这是访问模型对象信息和状态的便捷方式。它们提供有用的参数,例如instancecreatedupdated_fields,以满足您检查对象的需要。

答案 2 :(得分:0)

感谢大家的回答 - 仔细检查后,我可以得出结论,我绊倒了自己的双脚。

经过仔细检查甚至与pdb一起旅行后,我发现原始代码在最后一个super()之前混合了缩进 - \ t而不是\ s {4}。save()。

相关问题