2012-03-19 35 views
3

我有以下代碼:模型繼承 - 如何使用重寫的方法?

# apps/models.py : 

class Parent(models.Model): 
    name = models.CharField(max_length=80) 

    def __unicode__(self): 
     clist = ", ".join([x.__unicode__() for x in self.children.all()]) 
     return self.name + clist 

class Child(models.Model): 
    unit = models.ForeignKey(Parent, related_name='children') 
    desc = models.CharField(max_length=80) 

    def __unicode__(self): 
     return self.desc 

class ChildA(Child): 
    text = models.TextField() 

    def __unicode__(self): 
     return self.text[:40] 

ChildA類型的若干項。爲什麼當我詢問有關Parent__unicode__()時,我得到的字符串是__unicode__()方法的Child生成的,而不是ChildA__unicode__()方法生成的?

更新:

這是標準的行爲。除了以下答案之外,另一種可能的解決方案是inheritance cast

+0

請出示一些證據表明您正在做您認爲正在做的事。 – Marcin 2012-03-19 14:15:32

+0

**如果你剛開始接觸Django開發,我建議你使用[多表繼承(https://docs.djangoproject.com/en/dev/topics/db/models/#切莫多表繼承)。考慮使用更簡單,更少的容易出錯的方法。 [摘要基類(https://docs.djangoproject.com/en/dev/topics/db/models/#abstract-base-classes)會適合你。** – 2012-03-19 17:56:48

回答

4

這是繼承的標準行爲。 ParentChild直接相關,而不是ChildA。當你打電話給some_parent.children.all()時,你會得到一個Child實例的查詢集,很明顯,當你在其中的一個上調用unicode時,它會調用Child.__unicode__

UPDATE

有沒有真正的好辦法從父到子獲得。如果您正在使用MTI(多表繼承),則可以利用Django實現它的方式,即與父代一起使用OneToOneField。因此,父母與孩子之間也存在逆向關係,但您必須專門測試它。例如:

class Child(models.Model): 
    ... 
    def get_child(self): 
     if hasattr(self, 'childa'): 
      return self.childa 
     if hasattr(self, 'childb'): 
      return self.childb 
     ... 

這是不以任何方式理想,你需要小心,只要你繼承Child,這幾乎完全違反了抽象的OOP隨時更新此方法。

+0

很酷。所以至少我知道這不是我錯過的東西。這種行爲可能的解決方法是什麼,所以我可以訪問'some_parent.children.all()'的正確的子類方法? – Ohad 2012-03-19 14:48:56

+0

不錯!你也可以在get_child()方法的底部添加一個「assert False」語句,以在運行時獲得一些證據,表明某些派生類在列表中缺失 – 2017-07-26 11:08:34

0

爲什麼當我問有關父母的的Unicode()我 得到的回報串是由產生的一個unicode()方法 孩子?

因此,您並未調用Parent實例上的方法。這就是你看到這種行爲的原因。

+0

我呼籲了'Parent'的方法。 'Parent .__ unicode __()'方法遍歷所有子節點的__unicode __()'方法,但它是原始方法而不是重寫版本。 – Ohad 2012-03-19 13:48:29

+0

@哈哈我不相信你。顯示一些代碼及其輸出。 – Marcin 2012-03-19 13:52:34

+0

http://pastebin.com/fjU62hMa 看起來像系統引用像父模型一樣的繼承模型。 @Marcin – Ohad 2012-03-19 14:05:26

0

您可以通過使用super()關鍵字訪問父類的方法:

a = ChildA() 

#This will give you the normal method: 
print unicode(a) 

#super() will give you the parent's method: 
super(ChildA, a).__unicode__() 

你不能簡單地使用unicode()功能與後者調用,如super返回代理的對象,而不是一個對象它自己的權利。

這不是一種很好的代碼方式。把它留給班級來覆蓋行爲,因爲它認爲合適。