2011-05-20 15 views
3

我超然一個的ModelAdmin方法:密新問題要問的ModelAdmin

def response_change(self, request, obj): 
    # alter redirect location if 'source' is found in GET 
    response = super(JobOptions, self).response_change(request, obj) 
    source = request.GET.get('source', None) 
    if source: 
     response['location'] = source 
    return response 

而不是在每一個我想使它成爲一個混入模型重複這一點。

如果我做的:

def RedirectMixin(admin.ModelAdmin) 

然後:

然後我得到一個MRO錯誤。

但是,如果RedirectMixin不從admin.ModelAdmin繼承,那麼該方法不會被調用。

的另一個問題是如何推廣超()調用,因此不會有。

回答

11

首先硬編碼的超類,我相信你的意思class,而不是def在你的例子。

無論如何,使用Mixin的正確方法是首先在要繼承的類列表中使用它。所以:

class RedirectMixin(object): 

class MyModelAdmin(RedirectMixin, admin.ModelAdmin): 

這是因爲Python看起來通過所有父類在聲明的以便找到方法,並調用它找到的第一個。

至於超級,這不應該提及超類 - 這就是它的全部重點。它應該引用當前類:

return super(MyModelAdmin, self).__init__(self, *args, **kwargs) 

或其他。

在評論後編輯是的,mixin應該在super調用中引用它自己的類。考慮以下幾點:

In [1]: class BaseClass(object): 
    ...:  def my_function(self): 
    ...:   print 'base my_function' 
    ...:  

In [2]: class Mixin(object): 
    ...:  def my_function(self): 
    ...:   print 'mixin my_function' 
    ...:   super(Mixin, self).my_function() 
    ...: 

In [3]: class MyDerivedClass(Mixin, BaseClass): 
    ...:  pass 
    ...: 

現在,如果你實例化的子類,並調用其my_function法,MRO將像您期望的發生,即使密新不從BaseClass的繼承:

In [4]: m=MyDerivedClass() 

In [5]: m.my_function() 
mixin my_function 
base my_function 

錯誤你提到如果你不能讓Mixin成爲object的後裔 - 如果你不這樣做,它是一箇舊式的類,它不支持使用super。

+0

是的,我的意思是班級而不是def :) – 2011-05-20 12:00:46

+0

我很迷惑你對super()的評論。超級召喚生活在混合類中。它應該引用mixin類名嗎?當我嘗試時出現此錯誤:super()參數1必須是type,而不是classobj – 2011-05-20 12:01:53