问题描述
如何在Django 1.5中覆盖模型的元类?我在一些继承自抽象模型的模型上覆盖了元类,所以我可以设置适当的选择。例如
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 $ b $但是,当我升级到Django 1.5时,我现在得到错误: AttributeError:类型对象'BaseModel'没有属性'__metaclass__'
如何在1.5中覆盖模型的元类,否则在模型子类中动态设置字段属性
解决方案您可以使用内置
函数 type
like this:
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())
返回new_class
虽然我看到 type(ModelBase)是类型
,所以你基本上可以继承自类型
或者可能来自 Model .__ metaclass __
,这反过来 ModelBase
so ModelBase
是模型元类架构的顶端(当然类型
当然是:D)。
希望它有帮助!
How do you override a model's metaclass in Django 1.5? I was overriding the metaclass on some models inheriting from an abstract model so I could set appropriate choices. 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
However, when I upgraded to Django 1.5, I now get the error:
AttributeError: type object 'BaseModel' has no attribute '__metaclass__'
How do you override a model's metaclass in 1.5, or otherwise dynamically set field attributes in model subclasses?
解决方案 You can use the built-in
function type
like this:
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
Although I see that type(ModelBase) is type
so you basically could inherit from type
or maybe from Model.__metaclass__
which is in turn ModelBase
so ModelBase
is the top of the Model metaclass architecture (before type
of course :D ).
Hope it helps!
这篇关于Django 1.5中缺少元类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!