2012-02-21 41 views
4

這個問題不同於:Using __new__ on classes derived from Django's models does not work在Django模型類上設置__new__安全嗎?

問題問一個如何使__new__工作。

此問題要求:在Django模型中使用__new__有什麼缺陷?

特別是,我有下面的代碼,它存在用於在類上安裝類方法,它需要知道它來自哪個類(即它需要判斷它是否在子類上調用)。 這會以意想不到的方式炸燬嗎?

class Director(models.Model, Specializable, DateFormatter, AdminURL, Supercedable): # my own mixin classes 
    # all other properties etc snipped 

    @staticmethod # necessary with django models 
    def __new__(cls, *args, **kwargs): 
     Specializable.create_subclass_translator(cls, install = 'create_from_officer') 
     return models.Model.__new__(cls, *args, **kwargs) 

爲了完整起見,create_subclass_translator做這樣的事情:

@classmethod 
def create_subclass_translator(clazz, Baseclass, install=None):  
    def create_from_other_instance(selfclass, old_instance, properties): 
     if selfclass is Baseclass: raise TypeError("This method cannot be used on the base class") 
     # snipped for concision 
     return selfclass(**properties) 

    new_method = classmethod(create_from_other_instance) 

    if install and not hasattr(Baseclass, install): 
     setattr(Baseclass, install, new_method) 

    return new_method 

對於那些誰不知道這是完成時,類方法create_from_other_instance是一個工廠,模擬模型子類的實例更改通過複製基本類屬性,並正確設置ancestor_link屬性,將一個子類轉換爲另一個子類。

+0

這種複雜性的任何好理由? – 2012-02-21 16:40:11

+0

@Secator:首先,我不認爲這特別複雜。無論如何,原因是我需要在幾個類層次結構中具有相同的功能,並且如上所述,這些方法需要知道他們自己的類。要以另一種方式完成這一工作,需要複製和粘貼;或者每個基類的一個魔術輔助方法,它返回這個類本身;或者在類的定義之外執行安裝。所有這些邀請他們自己的微妙的錯誤。 – Marcin 2012-02-21 17:03:49

+0

你看過BaseModel類嗎?我很確定它也定義了__new__方法。我認爲,一旦你做了你自己的方法需要做的事情,你就需要調用super,否則這個類將不會實例化Django期望的方式。值得注意的是,你不會有一個Meta類或一個媒體類(在適當的情況下)。這些只是我腦海中的一些想法。 – 2012-02-21 17:40:54

回答

2

由於您正確地調用基類__new__,我不會期望有什麼意外 - 它應該是正常工作 - 如果做錯了,立即在實例化時失敗。

你不應該有任何微妙的錯誤 - 只要寫一些實例化這個類的單元測試。如果它變得「錯誤」,則測試將失敗。

+0

謝謝。當然,如果我知道可能的故障模式,我會針對這些故障模式進行測試;) – Marcin 2012-02-21 17:54:37

相關問題