简体   繁体   中英

How to propagate parent attributes in Django models?

Is there a way to propagate child attributes in parent class without having to access it by its related name? Please consider the following example:

class BaseA(models.Model):
    pass

class BaseB(models.Model):
    a = models.ForeignKey('BaseA')

class A(BaseA):
    base = models.OneToOneField('BaseA', related_name='related')
    field = models.IntegerField(default=0)

    def some_method(self):
        pass

class B(BaseB):
    base = models.OneToOneField('BaseB')

# code in view
model_b = B()
model_b.a.some_method()

I cannot access the some_method method because model_b.a returns a BaseA() instance instead of A() , if I want to access this method I have to:

model_b.a.related.some_method()
# or
model_b.a.related.field

Is there a way to propagate the properties and methods from the base class so I won't have to access using the related name?

Why not just add this to BaseA as a util:

class BaseA(models.Model):
    def some_method(self):
        return self.related.some_method()

If this is called for an non- A BaseA , it will raise an AttributeError which is plausible enough. If you want propagate all methods, you can override __getattr__ . This will only look at self.related if the attribute isn't found on the BaseA instance itself:

class BaseA(models.Model):
    def __getattr__(self, item):
        return getattr(self.related, item)

But adding attributes dynamically like this should be a last resort, one that makes code navigation and debugging harder, and renders other IDE features like code completion unusable. IMO, it is preferable to put all the methods you might actually want to call on BaseA instances in the class explicitly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM