I have the following models. How do I get access to the unicode of the inheriting tables (Team and Athete) from the Entity table? I\'m trying to display a l
This is a little ugly, but I think it should work:
entities = Entity.objects.all()
for entity in entities:
try:
print entity.team
except:
print entity.athlete
Check out http://docs.djangoproject.com/en/1.0/topics/db/models/#id7 for more on multi-table inheritance. Just be careful, because the Django ORM is inevitably a leaky abstraction and things you might normally do with objects can get you in trouble, or do unexpected things.
I answered a similar question a while ago. Have a look, I think one of the answers probably solves your problem as well.
How do I access the child classes of an object in django without knowing the name of the child class?
My answer from there was to add this to the parent class:
def get_children(self):
rel_objs = self._meta.get_all_related_objects()
return [getattr(self, x.get_accessor_name()) for x in rel_objs if x.model != type(self)]
Then you can call that function to get the children objects (in your case you will only have one) and then call the unicode function from that object.
If I undestand correctly, you are simply asking how to call the __unicode__
method of a given object.
Use unicode(instance)
and depending on the type of entity, the appropriate implementation will be called polymorphically.
I don't believe you have to do anything. If Entity
is never instantiated directly, you will never call the non-existent Entity.__unicode__
method. However, if you'd like to play it save, you could add a stub method in your Entity
class:
class Entity(models.Model):
def __unicode__(self):
pass
class Team(Entity):
def __unicode__(self):
return self.name
class Athlete(Entity):
def __unicode__(self):
return '%s %s' % (self.firstname, self.lastname)
You are now assured that any class which inherits from Entity
will have a __unicode__
method, and you can simply traverse them:
for thing in [TeamA(), AthleteA(), TeamB(), AthleteB()]:
print unicode(thing)
This answer from Carl Meyer to the question mentioned earlier by Paul McMillan might be what your looking for. A subtlety to this problem not captured in some of the answers is how to get at derived class instances from a QuerySet on Entity.
The Problem
for entity in Entity.objects.all()
print unicode(entity) # Calls the Entity class unicode, which is not what you want.
A Solution
Use the InheritanceCastModel
mixin in the answer linked above as a base class for Entity. You can then cast from Entity instances to the actual derived class instances. This is particularly handy when you want to use querysets on your parent class (Entity) but access the derived class instances.
class Entity(InheritanceCastModel):
# your model definition. You can get rid of the entity_type_list and type, as the
# real_type provided by InheritanceCastModel provides this info
class Athlete(Entity):
# unchanged
class Team(Entity):
# unchanged
for entity in Entity.objects.all():
actual_entity = entity.cast()
print unicode(actual_entity) # actual entity is a a Team or Athlete
From pure Python, you can use the isinstance
function:
class Entity:
def __init__(self):
if isinstance(self, Team):
print 'is team'
elif isinstance(self, Athlete):
print 'is athlete'
class Team(Entity):
def __unicode__(self):
return 'Team'
class Athlete(Entity):
def __unicode__(self):
return 'Athlete'