tun*_*rob 6 python django django-models
我正在为大约 10 个模型构建一些抽象模型。我需要以某种方式使 1 个字段不在抽象模型中声明,但必须在继承模型中声明。怎么做?有什么办法可以使用吗NotImplementedError?
如果不深入研究 Django,恐怕没有一种简单的方法可以实现这一点(如果可能的话)。
主要原因是Django 中Field不允许使用“hiding”名称。这意味着,如果您想在作为实例的抽象基类中声明一个抽象属性Field,您将无法在子类中重写它,这与正常的 Python 类继承范例相反。引用文档:
在普通的 Python 类继承中,子类可以覆盖父类的任何属性。在 Django 中,对于 Field 实例的属性是不允许的(至少目前不允许)。如果基类有一个名为“author”的字段,则您无法在继承该基类的任何类中创建另一个名为“author”的模型字段。
覆盖父模型中的字段会导致初始化新实例(指定在Model.init中初始化哪个字段)和序列化等方面的困难。这些是普通 Python 类继承不必以完全相同的方式处理的功能,因此 Django 模型继承和 Python 类继承之间的区别不是任意的。
此限制仅适用于 Field 实例的属性。如果您愿意,可以覆盖普通的 Python 属性。它也仅适用于 Python 所见的属性名称:如果您手动指定数据库列名称,则可以在多表继承的子模型和祖先模型中出现相同的列名称(它们是列)在两个不同的数据库表中)。
如果您覆盖任何祖先模型中的任何模型字段,Django 将引发 FieldError。
但是,如果该属性不是实例Field(尽管可能性很小),那么您将能够通过使用@property装饰器来实现您想要的效果。像这样的东西应该有效:
class Person(models.Model):
def __init__(self, *args, **kwargs):
super(Person, self).__init__(*args, **kwargs)
self.last_name
first_name = models.CharField(max_length=30)
@property
def last_name(self):
raise NotImplementedError
class Meta:
abstract = True
class Student(Person):
home_group = models.CharField(max_length=5)
last_name = "Doe" # "models.CharField()" will not work!
class BadStudent(Person):
home_group = models.CharField(max_length=5)
# "NotImplmentedError" will be raised when instantiating BadStudent()
Run Code Online (Sandbox Code Playgroud)
您可能还想看一下abc.abstractproperty。我不确定它如何与 Django 的模型继承一起工作。
| 归档时间: |
|
| 查看次数: |
1461 次 |
| 最近记录: |