Django 1.5中缺少元类 [英] Missing metaclass in Django 1.5

查看:142
本文介绍了Django 1.5中缺少元类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在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中缺少元类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆