gpt4 book ai didi

python - Django 管理界面不使用子类的 __unicode__()

转载 作者:太空狗 更新时间:2023-10-30 01:42:31 25 4
gpt4 key购买 nike

(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)

我没有实例化任何动物,因为这应该是一个虚拟类。我已经实例化了猫和狗,但在 AnimalHome 的管理页面中,我对动物的选择显示为“动物对象”(我猜是默认的 __unicode__()),而不是我为两个子类定义的 __unicode__。帮助。


我认为抽象基类问题对于这个问题来说是一个转移注意力的问题。即使 Animal 不应该是抽象的,我仍然有一个问题,由于某种原因,由于 ForeignKey 是在 Animal 而不是它的子类之一上定义的,所以调用父类(super class)方法而不是子类。在 OO 编程中,当您调用 object.method() 时,您应该获得最低子类的实现,并且您必须做额外的工作才能获得任何父类(super class)的实现。那么,为什么在子类上定义 __unicode__ 还不够——实际上问题可能是 __unicode__ 根本没有被调用,因为对 Animal 类的自省(introspection)表明它没有定义。所以也许如果我为 Animal 定义 __unicode__ 并让它调用子类的 __unicode__ 我可以获得预期的效果。


好的,我想我理解了 ORM 问题。这两个答案都帮助我理解了这一点,谢谢。在对此进行试验时,我发现当 Django 保存子类模型时,它会做两件事:(1) 它在父类(super class)的表中为子类对象创建一行,以及 (2) 它使子类表中的 PK 与在父类(super class)表中分配的 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!"

Lawrence 似乎对这个问题最中肯。 Cat 和 Dog 将有不相交的 PK 集(Animal 的任何子类都将具有与其父类(super class)的记录相同的 PK),但不幸的是 Django 没有在幕后执行任何工作:“我是动物。我知道动物有狗和猫的子类。具体来说,我是 3 号动物,而且我刚刚检查了一下,还有一只 3 号猫。这意味着我实际上是 3 号猫。”即使使用 Python 的自省(introspection),这看起来完全可能且非常合理(因为猫不会做任何动物不能做的事情)。谢谢大家。

最佳答案

ForeignKey(Animal) 就是对 Animal 表中一行的外键引用。底层 SQL 架构中没有任何内容表明该表正被用作父类(super class),因此您会得到一个 Animal 对象。

要解决此问题:

首先,您希望基类是非抽象的。无论如何,这对于 ForeignKey 都是必要的,并且还确保 Dog 和 Cat 将具有分离的主键集。

现在,Django 使用 OneToOneField 实现继承。正因为如此,具有子类实例的基类实例获得对该实例的引用,并适本地命名。这意味着您可以:

class Animal(models.Model):
def __unicode__(self):
if hasattr(self, 'dog'):
return self.dog.__unicode__()
elif hasattr(self, 'cat'):
return self.cat.__unicode__()
else:
return 'Animal'

这也回答了您向 Ber 提出的有关依赖于其他子类属性的 unicode() 的问题。您现在实际上是在子类实例上调用适当的方法。

现在,这确实表明,由于 Django 已经在幕后寻找子类实例,因此代码可以直接返回 Cat 或 Dog 实例而不是 Animal。您将不得不与开发人员讨论这个问题。 :)

关于python - Django 管理界面不使用子类的 __unicode__(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/313054/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com