首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在Django FeinCMS项目中子类化我的ModelAdmins?

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

Stack Overflow用户
提问于 2015-08-17 17:19:47
回答 1查看 364关注 0票数 1

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

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

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

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

EN

回答 1

Stack Overflow用户

发布于 2015-08-17 17:19:47

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

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

  1. 首先,附加到ModelAdmin的任何列表或字典(例如SharedModelAdmin.list_display)都是通过引用传递的,因此在多个ModelAdmins之间共享。这意味着扩展最终可能会在同一列表上执行两次操作(即使它附加到admin.py中的不同ModelAdmin).
  2. While我们在类级别定义ModelAdmin的设置,FeinCMS操作ModelAdmin的实例。

因此,为了让它正常工作,我们可以使用以下混入:

代码语言:javascript
运行
复制
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()

用法:

代码语言:javascript
运行
复制
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']
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32046741

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档