Model inheritance. How to use overridden methods?

I have the following code:

   # apps/ :

class Parent(models.Model):
    name = models.CharField(max_length=80)

    def __unicode__(self):
        clist = ", ".join([x.__unicode__() for x in self.children.all()])
        return + clist

class Child(models.Model):  
    unit = models.ForeignKey(Parent, related_name='children')
    desc = models.CharField(max_length=80)

    def __unicode__(self):
         return self.desc

class ChildA(Child):
    text = models.TextField()

    def __unicode__(self):
         return self.text[:40]


I have several elements of type ChildA

. Why, when I ask for the __unicode__()

appropriate Parent

, is the string I get in return the one generated by the method __unicode__()


and not the method __unicode__()




This is standard behavior. Other possible solutions in addition to below answers are inheritance inheritance


source to share

4 answers

This is the standard behavior for inheritance. Parent

is directly related to Child

, not ChildA

. When you call some_parent.children.all()

, you return a set of instance requests Child

, so obviously when you call unicode

on one of them, it calls Child.__unicode__



There's not a very good way to get from parent to child. If you are using MTI (Multiple Table Inheritance), you can take advantage of the way Django implements it, namely as OneToOneField

a parent. There is also parent-child feedback because of this, but you must specifically test it. For example:

class Child(models.Model):
    def get_child(self):
        if hasattr(self, 'childa'):
            return self.childa
        if hasattr(self, 'childb'):
            return self.childb


This is not ideal and you need to be careful to always update this method whenever you subclass Child

, which pretty much completely breaks abstraction in OOP.



You probably want an abstract base class.

Read the difference here ...



Why, when I ask the unicode () of the corresponding parent, the line I get in return is the one generated by the unicode () method of the Child?

It follows that you are not calling a method on an instance Parent

. This is why you see this behavior.



You can access the parent class method using the keyword super()


a = ChildA()

#This will give you the normal method:
print unicode(a)

#super() will give you the parent method:
super(ChildA, a).__unicode__()


You cannot just use the function unicode()

with the last call, as it super

returns a proxy for the object, not a native object.

This is not the best way to code. Leave it up to the class to override the behavior as you see fit.



All Articles