gpt4 book ai didi

python - 如何在 Django FeinCMS 项目中子类化我的 ModelAdmins?

转载 作者:太空宇宙 更新时间:2023-11-03 17:29:51 25 4
gpt4 key购买 nike

我有许多从 feincms.models.Base 扩展的模型,并在管理站点中使用 FeinCMS 项目编辑器(即它们都使用 feincms.admin.item_editor.ItemEditor 作为他们的 ModelAdmin)。

这些模型具有一些共享功能,我希望能够在共享 ModelAdmin 类中定义这些功能,然后我可以为每个模型进行扩展。

问题是,这与 FeinCMS 扩展不能很好地配合,导致意外的结果,例如重复的选项卡,扩展程序多次向 ModelAdmin 添加内容。

有没有办法在不弄乱扩展的情况下做到这一点?

最佳答案

这是可能的,但您必须采用稍微不同的语法。首先,解释一下。

ModelAdmins 的直接继承被破坏的原因是 FeinCMS 扩展操作 ModelAdmin 类的方式存在两个问题:

  1. 首先,附加到 ModelAdmin 的任何列表或字典(例如 SharedModelAdmin.list_display)都是通过引用传递的,因此在多个 ModelAdmin 之间共享。这意味着扩展程序最终可能会对同一列表执行两次操作(即使它附加到不同的 ModelAdmin)。
  2. 虽然在 admin.py 中,我们在级别定义ModelAdmin的设置,但 FeinCMS 操作 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']

关于python - 如何在 Django FeinCMS 项目中子类化我的 ModelAdmins?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32046741/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com