Django中的多态性
我有以下这些模型。我该如何从实体表中获取继承表(团队和运动员)的unicode?我想显示一个所有实体的列表,如果是团队就显示'名称',如果是运动员就显示'名字'和'姓氏'。
class Entity(models.Model):
entity_type_list = (('T', 'Team'), ('A', 'Athlete'))
type = models.CharField(max_length=2, choices=entity_type_list,default='P')
pictureurl = models.URLField('Picture Url', verify_exists=False, max_length=255, null=True, blank=True)
class Team(Entity):
name = models.CharField(max_length=100)
def __unicode__(self):
return self.name
class Athlete(Entity):
firstname = models.CharField(max_length=100)
lastname = models.CharField(max_length=100)
def __unicode__(self):
return '%s %s' % (self.firstname, self.lastname)
8 个回答
0
遍历所有的实体……如果这个实体的类别是'Athlete'(运动员),并且它有名字和姓氏:那就做点事情。
希望这对你有帮助。
编辑:嗯,我好像忘了怎么把这两种实体合并成一个列表。不太确定有没有简单的方法可以做到这一点。
1
在纯Python中,你可以使用 isinstance
这个函数:
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'
6
这是Carl Meyer对Paul McMillan之前提到的问题的回答,可能正是你想要的。这个问题有一个细节,在一些回答中没有提到,就是如何从Entity的查询集中获取派生类的实例。
问题
for entity in Entity.objects.all()
print unicode(entity) # Calls the Entity class unicode, which is not what you want.
解决方案
可以使用上面链接中提到的InheritanceCastModel
混入类作为Entity的基类。这样,你就可以将Entity的实例转换为实际的派生类实例。当你想在父类(Entity)上使用查询集,但又想访问派生类的实例时,这个方法特别有用。
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