【问题标题】:Double inheritance causes metaclass conflict双重继承导致元类冲突
【发布时间】:2012-06-30 13:23:48
【问题描述】:

我使用两个 django 包 - django-mptt(用于实现修改的预序树遍历的实用程序)和 django-hvad(模型翻译)。

我有一个模型类 MenuItem,我希望它扩展 TranslatableModel 和 MPTTModel,如下所示:

class MenuItem(TranslatableModel, MPTTModel):

但它会导致元类冲突:

(TypeError: Error when calling the metaclass bases 
metaclass conflict: the metaclass of a derived class 
must be a (non-strict) subclass of the metaclasses of all its bases)

这个问题的解决方案是什么?我希望我可以使用双重继承。

【问题讨论】:

  • 为什么需要多重继承?通常最好尽量避免。
  • 因为 MenuItem 有翻译(需要扩展 TranslatableModel)并且必须具有树层次结构(需要扩展 MPTTModel)。
  • MPTTModel 具有元类 MPTTModelBase,TranslatableModel 具有元类 TranslatableModelBase。就像@jathanism 链接到的问题中的答案一样,您必须设置元类,因为 Python 不知道要使用哪个基类的元类。

标签: python django database-design


【解决方案1】:

通常@shacki 的答案会起作用。但是,django-hvad 在后台覆盖了许多其他管理器/查询集类,这使得目前无法与 django-mptt/django-polymorphic 和朋友集成。

看看django-parler,它具有与 django-hvad 类似的 API 和管理集成,但也可以与其他软件包配合使用。表格布局相同,因此您应该可以轻松切换包。

【讨论】:

    【解决方案2】:

    很抱歉回答迟了,但我认为这对有同样问题的人会有所帮助。当您继承 MPTTModel 和另一个类时,请确保将 MPTTModel 放在首位,如下所示:

    class MenuItem(MPTTModel, TranslatableModel):
    

    【讨论】:

    【解决方案3】:

    您可能需要执行以下操作:

    class CombinedMeta(TranslatableModel.__metaclass__, MPTTModel.__metaclass__):
        pass
    class MenuItem(TranslatableModel, MPTTModel):
        __metaclass__=CombinedMeta
    

    这应该会给你你想要的,没有任何错误消息。

    【讨论】:

    • 在这种情况下,MenuItem.objects 将成为翻译经理。为了添加树管理器,必须手动添加 - tobjects = TreeManager()
    猜你喜欢
    • 2011-09-27
    • 2015-04-27
    • 2019-02-05
    • 1970-01-01
    • 2012-11-26
    • 2011-11-20
    • 2021-10-30
    • 2012-11-14
    相关资源
    最近更新 更多