覆盖Django中Model类的__getattribute__

时间:2009-12-09 09:57:51

标签: python django

在Django中,我需要创建一个模型,在该模型中,该模型的实例可以从该模型的另一个实例继承值,这些值相当于超类 - 子类类型关系。我在这个名为parent的模型中创建了一个字段,它是一个可选的自引用外键。然后,我想要覆盖__getattribute__方法,如下所示:

def __getattribute__(self, name):
    if models.Model.__getattribute__(self, 'parent') is None:
        return models.Model.__getattribute__(self, name)
    elif models.Model.__getattribute__(self, name) is not None:
        return models.Model.__getattribute__(self, name)
    else:
        return parent.__getattribute__(name)

此代码导致无限递归,因为Model类的__get__方法调用内置方法getattr作为第一个参数传入实例。

还有另一种方法可以完成我想要做的事情吗?

3 个答案:

答案 0 :(得分:3)

这样做很困难。

请重新考虑覆盖__getattribute__并使用普通旧属性。

我怀疑一个带有属性名称的简单“getter”会做你想要的东西而不会碰到任何魔法。

是的,您可能有几个相似的字段,但我认为简单明显的属性更适合Django ORM。

答案 1 :(得分:1)

您是否需要父母的属性影子自己的属性?如果没有,您最好覆盖__getattr__()而不是__getattribute__(),当实例本身具有此名称的属性时,不会调用def __getattr__(self, name): return getattr(self.parent, name)

{{1}}

答案 2 :(得分:1)

我认为覆盖__getattribute____getattr__可能导致性能成本问题。可能有更好的方法来解决这个问题:

  1. 在模型实例初始化时,如果可继承字段为空且对应的父字段不是,请执行setattr(self, field_name, getattr(self.parent, field_name))
  2. 跟踪模型实例字段更改。
  3. 在保存实例之前,请设置之前已覆盖但未更改为None的字段。
  4. 我正在为此开发一个Django应用程序:https://github.com/Altaisoft/django-inheritance