[英]Python polymorphic objects calling base class methods instead of subclass method
我在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()
結果僅列出了貓和狗。 但是,在致電時
query[0].ClassType
我只有animal
。 在“查詢”中的所有對象給我animal
,而我想要得到dog
或cat
取決於實例。 在Python多態世界中,我不了解什么?如何解決?
您可以使用點表示法(如屬性)訪問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
不應將ClassType
用作方法,而應使其成為實際字段,並在保存時存儲對象的類型。 否則,如您發現的那樣,當您查詢動物時,您只會得到動物,而不是子類型。
這個問題很舊,但是我遇到了同樣的問題,因此這是我的解決方案:
我使用了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()
然后,您可以忘記任何動物子類。 它對我有用,希望對您有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.