我想使用继承模型的Meta类中的属性来配置在继承树之上的抽象模型中定义的字段:
class NamedModel(models.Model):
class Meta:
abstract = True
verbose_name = 'object'
name = models.CharField("Name",
max_length=200,
db_index=True,
help_text="A meaningful name for this %s." % Meta.verbose_name)
# see what I'm trying to do here?
)
...
class OwnedModel(NamedModel):
class Meta(NamedModel.Meta):
verbose_name = 'owned object'
我希望OwnedModel表单名称字段上的帮助文本说“这个拥有对象的有意义的名称”。 但它没有:缺少“拥有”这个词,这表明在建立模型时使用NamedModel.Meta中的verbose_name,而不是OwnedModel.Meta。
这不是我对继承观点的期望:是否有某种方法可以创建字段,其中Meta.verbose_name引用非抽象模型类上的值,而不是抽象模型类上的值哪个领域被定义了?
还是我愚蠢?
(这可能看起来像一个微不足道的例子,它是:但它只是为了说明我想要做的更重要和更复杂的事情)
非常感谢提前。
答案 0 :(得分:2)
你为什么不尝试上课。
class BaseNamedModelMeta:
abstract = True
verbose_name = "your text"
然后继承并覆盖你想要的任何东西:
class OwnedModel(NamedModel):
class Meta(BaseNamedModelMeta):
verbose_name = 'owned object'
答案 1 :(得分:1)
我认为这是因为使用了Meta.verbose_name并且在解析类NamedModel时创建了NamedModel.name。所以稍后,当类OwnedModel被解析时,没有机会改变任何东西。
也许您可以稍后在OwnedModel.name上设置help_text属性,但这也可能会更改NamedModel.name。
在类似情况下,我将变量部分放在模型的class属性中(而不是Meta),然后使用运行时方法/属性生成我需要的文本。
答案 2 :(得分:1)
事实上我最终做了以下事情。给基本模型一个dynamic_field_definition()类方法,该方法可用于修补字段,cls参数是正确的(继承)类。这意味着cls的Meta属性属于正确的子级,而不是原始的基础。
然后我连接该方法以调用class_prepared信号,这样你就可以知道其他一切准备好了。
class NamedModel(models.Model):
...
@classmethod
def dynamic_field_definition(cls):
pass
def dynamic_field_definition(sender, **kwargs):
if issubclass(sender, NamedModel):
sender.dynamic_field_definition()
class_prepared.connect(dynamic_field_definition)
然后,通过该类方法重新配置随模型类变化的字段属性(或者更可能是在派生类中重写的方法)。
将Django模型的最后一点OO-ness引入Django模型是一种稍微晦涩的方式,但它适用于我的目的。