sha*_*nyu 27 python django inheritance django-models
假设我有一个继承自SuperFoo的模型Foo:
class SuperFoo(models.Model):
name = models.CharField('name of SuperFoo instance', max_length=50)
...
class Foo(SuperFoo):
... # do something that changes verbose_name of name field of SuperFoo
Run Code Online (Sandbox Code Playgroud)
在类Foo中,我想覆盖SuperFoo的name字段的verbose_name.我可以吗?如果没有,是在模型表单定义中设置标签以使其显示在模板中的最佳选项吗?
小智 53
我用过的一个简单的黑客是:
class SuperFoo(models.Model):
name = models.CharField('name of SuperFoo instance', max_length=50)
...
class Meta:
abstract = True
class Foo(SuperFoo):
... # do something that changes verbose_name of name field of SuperFoo
Foo._meta.get_field('name').verbose_name = 'Whatever'
Run Code Online (Sandbox Code Playgroud)
And*_*ker 10
请记住,修改Foo._meta.fields也会影响超类 - 因此只有在超类是抽象的时候才真正有用,我已经将@Gerry放弃的答案包装成可重复使用的类装饰器:
def modify_fields(**kwargs):
def wrap(cls):
for field, prop_dict in kwargs.items():
for prop, val in prop_dict.items():
setattr(cls._meta.get_field(field), prop, val)
return cls
return wrap
Run Code Online (Sandbox Code Playgroud)
像这样使用它:
@modify_fields(timestamp={
'verbose_name': 'Available From',
'help_text': 'Earliest date you can book this'})
class Purchase(BaseOrderItem):
pass
Run Code Online (Sandbox Code Playgroud)
上面的示例更改了继承字段"timestamp"的verbose_name和help_text.您可以传入与要修改的字段一样多的关键字参数.
看看Django-CMS是如何做到这一点的,它们会覆盖db_table继承自的模型中的字段CMSPlugin.基础知识(我也用于我自己的东西)归结为:
class SuperFooMetaClass(ModelBase):
def __new__(cls, name, bases, attrs):
new_class = super(SuperFooMetaClass, cls).__new__(cls, name, bases, attrs)
new_class._meta.verbose_name = "...." # perhaps only if not customized
return new_class
class SuperFoo(models.Model):
__metaclass__ = SuperFooMetaClass
....
Run Code Online (Sandbox Code Playgroud)
您可以添加一些检查,例如,仅更新子类(不是直接类型),或仅在未自定义值时更新.
| 归档时间: |
|
| 查看次数: |
7989 次 |
| 最近记录: |