2

我在 Django 中有以下模型。我有理由不创建Animal抽象基类。

class Animal(models.Model):
    sound = "none"
    def ClassType(self):
        return 'animal'

class Cat(Animal):
    animal_id = models.OneToOneField(Animal,parent_link=True)
    sound = "meow"
    def ClassType(self):
        return 'cat'

class Dog(Animal):
    animal_id = models.OneToOneField(Animal,parent_link=True)
    sound = "bow"
    def ClassType(self):
        return 'dog'

我查询一组动物为

query = Animal.objects.all()

结果是必然只有 Dogs 和 Cats 的列表。但是,在调用

query[0].ClassType

我只得到animal. “查询”中的所有对象都会在animal我想要获取dogcat取决于实例时给我。在 Python 多态世界中我不了解什么以及如何解决它?

4

3 回答 3

0

您可以使用点表示法(如属性)访问 dog 和 cat 对象。该查询Animal.objects.all()将返回所有动物,其中包括所有猫和狗。

qs = Animal.objects.all()
for animal in qs:
    try:
        obj = animal.cat
        # its a cat
    except AttrbuteError:
        # its a dog
        obj = animal.dog

如您所见,在识别哪一只是狗和哪一只是猫时有一个小故障,一个好的方法是在您的动物模型中设置一个临时属性:

class Animal(models.Model):
    sound = "none"

    def is_cat(self):
        if not hasattr(self, '_is_cat'):
            self._is_cat = Cat.objects.filter(animal_id=self).exists()
        return self._is_cat

现在你可以简单地做:

qs = Animal.objects.all()
for animal in qs:
    if animal.is_cat():
        # this is a cat
    else:
        # dog
于 2013-01-09T19:11:24.113 回答
0

与其创建ClassType方法,不如将其设置为实际字段,并在保存时存储对象的类型。否则,正如您所发现的,当您查询 Animals 时,您只会得到 Animals,而不是子类型。

于 2013-01-09T19:53:54.110 回答
0

这个问题很老,但我遇到了同样的问题,所以这是我的解决方案:

我使用了django_polymorphic应用程序,它非常有用,原因有很多,但它提供了相应模型实例的属性及其名称,您可以使用它来解决您的问题。

因此,您可以将基类更改为如下所示:

class Animal(PolymorphicModel):
    sound = "none"

    def ClassType(self):
        polymorphic_attr_name = self.name.lower().replace(" ", "")  # Get the name of the attribute that points to the instance
        if polymorphic_attr_name == 'animal':
            return 'animal'
        instance = getattr(self, polymorphic_attr_name)
        return instance.ClassType()

然后你可以忘记任何动物子类。它对我有用,希望这会有所帮助。

于 2016-07-07T15:17:08.550 回答