如何在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中覆盖模型的元类,或者在模型子类中动态设置字段属性?
答案 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