gpt4 book ai didi

python - 访问 Python Django 中的子方法

转载 作者:太空宇宙 更新时间:2023-11-03 17:53:22 24 4
gpt4 key购买 nike

我有一个现实生活中的案例,可以使用多态性来解决,就像在 Java 中一样,我们可以创建属于同一类型的对象列表。然而,每个对象可能有一个覆盖或额外的字段。

class Animal(models.Model):
name = models.CharField(max_length=30)

def speak(self):
return "I am an animal"


class Cat(Animal):

def speak(self):
""" OVERRIDE """
return "MEAOO"


class Dog(Animal):

def speak(self):
""" OVERRIDE """
return "WOOOOF"

我现在需要的是获取所有动物,但让每个动物使用它的语音方法。我无法做到这一点,如下所示。

>>> c = Cat(name="MyCAT")
>>> c.save()
>>> d = Dog(name="MyDOG")
>>> d.save()
>>> animals = Animal.objects.all()
>>> animals
[<Animal: Animal object>, <Animal: Animal object>]
>>> for a in animals:
... a.speak()
...
'I am an animal'
'I am an animal'
>>>

对我来说,输出应该如下所示

'MEAOO'
'WOOOOF'

有没有办法在 Django 中做类似的事情?

最佳答案

我最近遇到了这个问题。我有几个子类,它们的“说话”方法都略有不同。

我基本上做的是在我的父类中创建一个downcast函数,它检查相关的子类实例。这是有效的,因为当你对模型进行子类化时,django 通过 OneToOneField 链接它们,这可以通过两种方式遍历:

class Animal(models.Model):
name = models.CharField(max_length=30)
_downcast = None
# to store the subclass instance, so that
# subsequent calls don't hit the database

def speak(self):
return "I am an animal"

def downcast(self):
if self._downcast is None:
if hasattr(self, 'cat'):
self._downcast = self.cat
elif hasattr(self, 'dog'):
self._downcast = self.dog

return self._downcast


class Cat(Animal):
def speak(self):
""" OVERRIDE """
return "MEAOO"


class Dog(Animal):
def speak(self):
""" OVERRIDE """
return "WOOOOF"

基本上,您只是有点...去尝试一下,然后询问您的数据库该 Animal 是否确实有相关的 Cat 行:

>>> a = Animal.objects.all().first() #let's assume this is a cat
>>> a.speak()
I am an animal
>>> a.downcast().speak()
MEAOO

当然,这会查询数据库,因此性能可能会受到影响。考虑您自己的场景并运行一些测试,看看这是否适合您。

关于python - 访问 Python Django 中的子方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28822065/

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