Model inheritance. How to use overridden methods?

I have the following code:

   # apps/models.py :

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

    def __unicode__(self):
        clist = ", ".join([x.__unicode__() for x in self.children.all()])
        return self.name + 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__()

Child

and not the method __unicode__()

ChildA

?

Update:

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

+3


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__

.

UPDATE

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.

+4


source


You probably want an abstract base class.



Read the difference here ... https://docs.djangoproject.com/en/dev/topics/db/models/#abstract-base-classes

0


source


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.

0


source


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.

0


source







All Articles