Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python Django中访问子方法_Python_Django - Fatal编程技术网

在Python Django中访问子方法

在Python Django中访问子方法,python,django,Python,Django,我有一个真实的案例,可以使用多态性解决,比如在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): """ OV

我有一个真实的案例,可以使用多态性解决,比如在
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'
>>> 

在Django还有类似的事情吗

我最近有这个问题。我有几个子类,它们都有稍微不同的“speak”方法

我基本上是在父类中创建一个
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"
基本上,你只是有点……试试看,问问你的数据库这个
动物
实际上是否有相关的
行:

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

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

这是因为你把动物从<代码>动物< /代码>对象中提取出来,它定义了<代码>语言(<)>代码>方法:“我是动物”。如果您从相应的模型中查询,您的数据应该正确实例化。有关模型继承的详细信息,请参阅:您需要子类…请尝试modelutils
>>> a = Animal.objects.all().first() #let's assume this is a cat
>>> a.speak()
I am an animal
>>> a.downcast().speak()
MEAOO