Django中的多态性

dan*_*roa 1 python django inheritance

我有以下型号.如何从Entity表中访问继承表(Team和Athete)的unicode?我正在尝试显示所有显示"名称"的实体的列表,如果Team和'firstname'和'lastname',如果运动员.

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)
Run Code Online (Sandbox Code Playgroud)

zlo*_*ady 5

从卡尔·迈耶答案由保罗·麦克米兰前面提到的问题可能是你在找什么.在一些答案中未捕获的这个问题的一个微妙之处是如何从Entity上的QuerySet获取派生类实例.

问题

for entity in Entity.objects.all()
  print unicode(entity) # Calls the Entity class unicode, which is not what you want.
Run Code Online (Sandbox Code Playgroud)

一个办法

使用InheritanceCastModel上面链接的答案中的mixin作为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
Run Code Online (Sandbox Code Playgroud)