2009-11-05 52 views
0

我的應用程序使用類繼承來儘量減少我的模型重複。我的models.py看起來有點像這樣:在Django的父級實例中找到一個子實例最簡單的方法是什麼?

class BaseModel(models.Model): 
    title = models.CharField(max_length=100) 
    pub_date = models.DateField() 

class Child(BaseModel): 
    foo = models.CharField(max_length=20) 

class SecondChild(BaseModel): 
    bar = models.CharField(max_length=20) 

現在大部分的時間,我的意見和模板只處理與兒童或SecondChild的實例。然而,偶爾有一種情況,我有一個BaseModel實例,需要弄清楚哪個類正在從這個實例繼承。

給定一個BaseModel的實例,我們稱它爲base,Django的ORM提供base.child和base.secondchild。目前,我有一個方法循環遍歷所有這些方法。它看起來是這樣的:

class BaseModel(models.Model): 
    ... 
    def get_absolute_url(self): 
     url = None 
     try: 
     self.child 
     url = self.child.get_absolute_url() 
     except Child.DoesNotExist: 
     pass 
     if not url: 
     try: 
      self.secondchild 
      url = self.secondchild.get_absolute_url() 
     except SecondChild.DoesNotExist: 
      pass 
     if not url: 
     url = '/base/%i' % self.id 
     return url 

這是絕望醜陋的,並與我擁有的每一個額外的孩子班級醜陋。有沒有人有更好的,更pythonic的方式來做到這一點?

回答

0

這個問題的各種形式定期彈出。 This answer演示了一種通用方法,可以將父類型「轉換」爲其適當的子類型,而無需查詢每個子類型表。這樣你就不需要在父類中定義一個包含所有情況的怪物get_absolute_url,你只需要轉換爲子類型並正常調用get_absolute_url即可。

0

我沒有測試過這一點,但它可能是值得擺弄:

def get_absolute_url(self): 
    subclasses = ('child', 'secondchild',) 

    for subclass in subclasses: 
     if hasattr(self, subclass): 
      return getattr(self, subclass).get_absolute_url() 

    return '/base/%i' % self.id 
+1

最後如果不是真的需要,是嗎? – Macke 2009-11-05 21:36:21

+0

謝謝!男人,我覺得很愚蠢。 – Udbhav 2009-11-05 21:47:08

0

我沒有使用Django搞砸inheitance多,所以我想你不能覆蓋模型get_absolute_url()班?

也許訪問者模式可以幫助,如果有很多功能,需要在許多不同的地方這一點。

+0

我重寫了它,但有時候,我必須使用父類,它無法訪問它的子節點的get_absolute_url,直到我確定它是什麼樣的子節點爲止。 – Udbhav 2009-11-05 21:36:21

相關問題