在Django 1.5中缺少元类

时间:2013-05-14 21:02:29

标签: python django django-models

如何在Django 1.5中覆盖模型的元类?我在一些继承自抽象模型的模型上覆盖了元类,因此我可以设置适当的选择。 e.g。

class BaseModel(models.Model):

    field_with_choices = models.CharField(max_length=100)

    class Meta:
        abstract = True

class MyModelMetaClass(BaseModel.__metaclass__):
    def __new__(cls, *args, **kwargs):
        new_class = super(MyModelMetaClass, cls).__new__(cls, *args, **kwargs)
        field = new_class._meta.get_field('field_with_choices')
        choices = field._choices = []
        choices.extend(get_choices())
        return new_class

class MyModel(BaseModel):

    __metaclass__ = MyModelMetaClass

然而,当我升级到Django 1.5时,我现在收到错误:

AttributeError: type object 'BaseModel' has no attribute '__metaclass__'

如何在1.5中覆盖模型的元类,或者在模型子类中动态设置字段属性?

2 个答案:

答案 0 :(得分:5)

您可以像这样使用built-in函数type

class MyModelMetaClass(type(BaseModel)):
    def __new__(cls, *args, **kwargs):
        new_class = super(MyModelMetaClass, cls).__new__(cls, *args, **kwargs)
        field = new_class._meta.get_field('field_with_choices')
        choices = field._choices = []
        choices.extend(get_choices())
        return new_class

虽然我看到type(ModelBase) is type,所以你基本上可以继承type或者Model.__metaclass__继承ModelBase,所以ModelBase是最重要的模型元类架构(当然在type之前:D)。

希望它有所帮助!

答案 1 :(得分:0)

如果我理解正确,django 1.5正在使用six进行兼容性管理。根据{{​​3}},正确的方法如下:

from six import with_metaclass

class Meta(type):
    pass

class Base(object):
    pass

class MyClass(with_metaclass(Meta, Base)):
    pass