我正在覆盖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)
然后:
def MyModel(admin.ModelAdmin, RedirectMixin)
然后我收到MRO错误。
但是,如果RedirectMixin没有从admin.ModelAdmin继承,则不会调用该方法。
另一个问题是如何推广super()调用,因此它没有硬编码的超类。
答案 0 :(得分:11)
首先,我在你的例子中假设你的意思是class
而不是def
。
无论如何,使用Mixin的正确方法是首先在要继承的类列表中使用它。所以:
class RedirectMixin(object):
和
class MyModelAdmin(RedirectMixin, admin.ModelAdmin):
这是因为Python按照声明的顺序浏览所有父类以查找方法,并调用它找到的第一个方法。
至于super,这根本不应该提到超类 - 这就是它的全部意义。它应该引用当前的类:
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
方法,那么即使Mixin不从BaseClass继承,MRO也会按预期发生:
In [4]: m=MyDerivedClass()
In [5]: m.my_function()
mixin my_function
base my_function
如果你没有让Mixin
成为object
的后代,那么你提到的错误就会出现 - 如果你不这样做,那就是一个老式的类,它不支持使用super。