我可以使django模型对象不可变吗?

时间:2011-03-08 18:22:26

标签: django django-models

我的代码中有些地方我想暂时更改模型对象的某些属性而不更改数据库中的数据。显然Django和Python使这很容易做到,我只需要在不调用save的情况下设置属性。

但是我想知道是否有一个使对象不可变的常见模式,所以我不小心在以后的某个地方调用save,并搞砸了我数据库中的数据。也许“不可变”在这里不是正确的词,它更像是将对象与模型分离,因此数据无法返回数据库。

我的第一个想法是只是覆盖save方法什么都不做,这还不够吗?

4 个答案:

答案 0 :(得分:4)

以这种方式覆盖普通模型的save()方法可能很麻烦,因此您应该考虑使用proxy modelsave()方法,如果调用则抛出异常。< / p>

答案 1 :(得分:4)

这里最简单的做法是,如果你想让你的实例不可变,那就是写一个小包装器:

def _model_save_base(*args, **kwargs):
    raise NotImplementedError("Cannot save a frozen instance.")

def freeze_instance(obj):
    obj.save_base = _model_save_base

然后你可以在你的对象上调用freeze_instance:

blog = Blog.objects.get(name='Django')
blog.save()  # writes to the database
freeze_instance(blog)
blog.save()  # NotImplementedError

您可以通过制作自定义异常来改善这一点。或者您可以将freeze_instance添加到您的Blog模型中。但这主要是风格。

答案 2 :(得分:4)

我知道这个问题已经过时了,但仍然非常重要。

迄今为止我提出的最好的,如果有点简单的解决方案看起来像这样;

class ModelName(models.Model):
    # fields, etc...
    def save(self, *args, **kwargs):
        if self.pk:
            raise ValidationError("you may not edit an existing %s" % self._meta.model_name)
        super(ModelName, self).save(*args, **kwargs)

这样,用户就会被告知他们正在执行的操作不受支持,而不是只是默默地失败。

答案 3 :(得分:1)

还有一些库,如django-immutablemodeldjango-immutablefield,它们为不可变模型提供了更全面的API。