Reputation: 247
In Django, I need to create a model in which an instance of that model can inherit values from another instance of that model in what amounts to a superclass-subclass type relationship. I created a field in this model called parent, which is an optional self-referencing foreign key. I then want to override the __getattribute__ method as follows:
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)
This code causes an infinite recursion because the __get__ method of the Model class calls the built-in method getattr passing in the instance as the first parameter.
Is there another way to accomplish what I'm trying to do?
Upvotes: 2
Views: 3404
Reputation: 1752
I suppose that overriding __getattribute__
or __getattr__
may lead to performance cost. Probably there is a better way to solve this problem:
setattr(self, field_name, getattr(self.parent, field_name))
.None
.I'm developing a Django app for that: https://github.com/Altaisoft/django-inheritance
Upvotes: 1
Reputation: 391818
This is fraught with difficulty when done this way.
Please reconsider overriding __getattribute__
and use a plain old properties for this.
I suspect that a simple "getter" with a property names will do eveything you want without bumping into any magic.
Yes, you may have several similar fields, but I think that simple, obvious properties fit better with the Django ORM.
Upvotes: 3
Reputation: 33180
Do you need that parent's attributes shadow own ones? If not, you'd better overwrite __getattr__()
instead of __getattribute__()
which is not called when instance itself has property with this name:
def __getattr__(self, name):
return getattr(self.parent, name)
Upvotes: 2