Reputation: 1719
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 items of type ChildA
. Why when I ask for a __unicode__()
of the relevant Parent
, the string I get in return is the one generated by the __unicode__()
method of Child
and not the __unicode__()
method of ChildA
?
Updates:
This is standard behavior. Another possible solutions in addition to answers below is an inheritance cast
Upvotes: 5
Views: 3540
Reputation: 239220
This is standard behavior for inheritance. Parent
is related directly with Child
, not ChildA
. When you call some_parent.children.all()
, you get back a queryset of Child
instances, so obviously, when you call unicode
on one of those, it's calling Child.__unicode__
.
UPDATE
There's not really a good way to get from a parent to the child. If you're using MTI (Multiple Table Inheritance), you can take advantage of the way Django implements it, namely as a OneToOneField
with the parent. Because of that, there's also a reverse relationship on the parent to the child, but you must specifically test for 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
...
It's not ideal by any means, and you need to be careful to always update this method whenever you subclass Child
, which pretty much totally violates abstraction in OOP.
Upvotes: 5
Reputation: 22808
You can access the parent class's method by using the super()
keyword:
a = ChildA()
#This will give you the normal method:
print unicode(a)
#super() will give you the parent's method:
super(ChildA, a).__unicode__()
You cannot simply use the unicode()
function with the latter call, as super
returns a proxy to the object, rather than an object in its own right.
This is not a good way to code. Leave it up to the class to override behaviour as it sees fit.
Upvotes: 0
Reputation: 49816
Why when I ask for a unicode() of the relevant parent the string I get in return is the one generated by the unicode() method of Child ?
It follows that you are not calling the method on a Parent
instance. That is why you are seeing this behaviour.
Upvotes: 0
Reputation:
You probably want an abstract base class.
Read up on the difference here... https://docs.djangoproject.com/en/dev/topics/db/models/#abstract-base-classes
Upvotes: 0