【问题标题】:Django __getitem__ on model: metaclass conflict模型上的 Django __getitem__:元类冲突
【发布时间】:2012-12-13 08:44:38
【问题描述】:

在 Django 中,我想在类级别实现__getitem__(所以在下面的示例中,我想做Alpha['a'])。我发现我需要一个元类:就像它需要在类上实现以使其在实例上可访问一样,它必须在元类上实现才能在类级别上使用它,据我所知。

class AlphaMeta(type):

    a = 7

    def __getitem__(self, key):
        return getattr(self, key)

class Alpha(models.Model):

    value = models.CharField(max_length = 64, default = '')

    __metaclass__ = AlphaMeta

print Alpha['a']

问题是我收到以下错误。如果 Alpha 是一个普通的新式类 (class Alpha(object)),它可以正常工作,但对于更复杂的基础,它需要更多。但是,我不明白它想从我这里得到什么,因为我不明白 the metaclasses of all it's bases 是什么。

metaclass conflict: the metaclass of a derived class must be a 
(non-strict) subclass of the metaclasses of all it's bases

我对元类很陌生;非常感谢任何提示!

编辑:模型字段进入 Alpha 而不是 AlphaMeta

【问题讨论】:

    标签: python django metaclass magic-methods


    【解决方案1】:

    我真的建议避免弄乱模型的元类,因为您很容易遇到一些难以调试的奇怪问题。无论如何,如果您仍然想这样做,错误消息会告诉您需要做什么。

    AlphaMeta 需要是models.Model 的元类的子类,即django.db.models.base.ModelBase。所以试试

    from django.db.models.base import ModelBase
    
    class AlphaMeta(ModelBase):
        …
    

    您可能还想在 KeyError 的情况下调用超类实现。

    【讨论】:

    • 感谢您的回答!那我可能不会走那条路,谢谢你的警告。无论如何它有效。我担心它可能会为元类制作一张桌子,但它并没有,所以一切都很好。
    • 为什么不直接将a = 7 添加到Alpha,然后使用Alpha.a
    • 这是一个简化的例子 :) 例如,我更方便地使用item.value for item in Model。但确实没有什么是传统方式完全不可能的。
    • 很公平 :) 您可能想发布另一个问题来解释您要解决的问题。
    猜你喜欢
    • 2014-12-22
    • 2012-02-02
    • 2010-11-05
    • 2018-01-15
    • 1970-01-01
    • 1970-01-01
    • 2011-12-18
    • 2015-12-18
    • 1970-01-01
    相关资源
    最近更新 更多