(Django 1.x,Python 2.6.x)
我有以下模型:
class Animal(models.Model):
pass
class Cat(Animal):
def __unicode__(self):
return "This is a cat"
class Dog(Animal):
def __unicode__(self):
return "This is a dog"
class AnimalHome(models.Model):
animal = models.ForeignKey(Animal)
我没有实例化动物,因为这应该是一个虚拟类。我已经实例化了 Cats 和 Dogs,但是在 AnimalHome 的管理页面中,我对 Animals 的选择显示为“Animal object”(我猜是默认的 __unicode__()),而不是我为两个子类定义的 __unicode__。帮助。
我认为,抽象基类问题是这个问题的一个红鲱鱼。即使 Animal 不应该是抽象的,我仍然有一个问题,由于某种原因,ForeignKey 是在 Animal 而不是它的子类之一上定义的,因此调用的是超类方法而不是子类。在 OO 编程中,当您调用 object.method() 时,您应该获得最低子类的实现,并且您必须做额外的工作才能获得任何超类的实现。那么为什么在子类上定义 __unicode__ 是不够的——实际上问题可能是根本没有调用 __unicode__ 因为对 Animal 类的自省表明它没有被定义。所以也许如果我为 Animal 定义 __unicode__ 并让它调用子类'
好的,我想我了解 ORM 问题。这两个答案都帮助我理解了这一点,谢谢。在对此进行试验时,我发现当 Django 保存子类模型时,它会做两件事:(1)它为超类表中的子类对象创建一行,以及(2)它使子类表中的 PK 与在超类表中分配的 PK。子类表中的这个 PK 被命名为 superclass_ptr。基于此,我炮制了以下内容。我很感激反馈。
Class Animal(models.Model)
def __unicode__(self):
if Dog.objects.filter(pk=self.pk).count() > 0:
return unicode(Dog.objects.get(pk=self.pk))
elif Cat.objects.filter(pk=self.pk).count() > 0:
return unicode(Cat.objects.get(pk=self.pk))
else:
return "An Animal!"
劳伦斯似乎在这个问题上最准确。Cat 和 Dog 将有不相交的 PK 集(并且 Animal 的任何子类都将具有与其超类的记录相同的 PK),但不幸的是 Django 并没有在幕后执行任何工作,例如:“我是动物。我知道动物有子类Dog和Cat。具体来说,我是3号动物,而且我刚刚查了一下,也有3号猫。这意味着我实际上是3号猫”。尽管使用 Python 的内省,这似乎完全有可能并且非常合理(因为 Cat 不会做 Animal 自己做不到的任何事情)。谢谢你们。