これは可能ですが、少し異なる構文を採用する必要があります。まず、説明です。
ModelAdmins の単純な継承が壊れている理由は、FeinCMS 拡張機能がModelAdmin
クラスを操作する方法に関する 2 つの問題のためです。
ModelAdmin
まず、 (例: )に添付されたリストまたは辞書SharedModelAdmin.list_display
は参照によって渡されるため、複数の ModelAdmin 間で共有されます。これは、拡張機能が同じリストに対して操作を 2 回実行することになる可能性があることを意味します (別の にアタッチされていてもModelAdmin
)。
- 私たちではの設定をクラス
admin.py
レベルで定義しますが、FeinCMS は ModelAdmin のインスタンスを操作します。ModelAdmin
したがって、それを機能させるために、次の mixin を使用できます。
class Faked(object):
"A fake class to use to stand in for True in ExtendableModelAdminMixin."
pass
class ExtendableModelAdminMixin(object):
"""ModelAdmin mixin to allow ModelAdmins to be extended (i.e.
subclassed) without messing
up the Feincms extension registering mechanism.
Technical note: the reason we do this is because otherwise references
get preserved across different ModelAdmins, which means the ModelAdmins
fail Django's checks.
The straightforward declarative syntax of ModelAdmins sets
attributes at the class level, but FeinCMS's
initialize_extensions() method overrides them on the
instance level. So in our mixin we do a deepcopy of any
instance level attributes before initializing the extensions.
"""
def __init__(self, *args, **kwargs):
# Set the _extensions_initialized attribute to prevent
# extensions being initialized just yet
self._extensions_initialized = Faked
super(ExtendableModelAdminMixin, self).__init__(*args, **kwargs)
# Before running extensions, copy any lists so we don't
# preserve references across different ModelAdmin subclasses
# TODO - include any other ModelAdmin properties that
# are causing issues.
for attr_name in ('list_display',
'fieldsets',
'search_fields', 'list_filter'):
original = getattr(self, attr_name, [])
copied_attr = deepcopy(original)
setattr(self, attr_name, copied_attr)
# Now we're ready to initialize extensions
del(self._extensions_initialized)
self.initialize_extensions()
使用法:
class SharedModelAdmin(ExtendableModelAdmin, ItemEditor):
# Declare some defaults here, as usual
list_display = ['field_one', 'field_two']
class MyModelAdmin(SharedModelAdmin):
def __init__(self, *args, **kwargs):
super(MyModelAdmin, self).__init__(*args, **kwargs)
# Override things at the instance level
self.list_display += ['field_three']