将django属性设为抽象属性

时间:2019-06-14 11:27:39

标签: django python-3.6

我有一个父类,应该由将成为Django模型的子类继承。子类都具有一个公共属性x,因此它应该是父类的抽象属性。子代之间的区别在于该属性是Django模型属性还是直接设置。

class A(Model, metaclass=abc.ABCMeta):
    class Meta:
        abstract = True

    @property
    @abc.abstractmethod
    def x(self):
        pass

class B(A):
    x = "hello"

class C(A):
    x = models.CharField(max_length=100, default='defaultC')

class D(A):
    x = models.CharField(max_length=50, default='defaultD')

因此,在我的示例中,对于某些子类,属性x是已知的,但在其他情况下,则需要选择该属性。但是有一件事是,类A的所有后代都需要一个x属性,因为它是一个公共属性,必须由任何后代定义。

问题是,如果我实例化CD的类,则会得到以下信息:

TypeError: Can't instantiate abstract class C with abstract methods x

我认为问题出在Django元类的幕后。它删除了所有django模型属性,并用延迟的属性或某些属性替换了它们,因此该属性从未真正定义过。

我可以尝试将模型属性上移到类A上,并根据需要让子类作为静态值覆盖:

class A(Model, metaclass=abc.ABCMeta):
    class Meta:
        abstract = True

    x = models.CharField(max_length=100)

class B(A):
    x = "hello"

class C(A):
    x = models.CharField(max_length=100, default='defaultC')

class D(A):
    x = models.CharField(max_length=50, default='defaultD')

我的问题是,这感觉不太抽象。 CD仍需要覆盖x来设置其默认值和最大长度。还让我担心的是,通常在代码中使用类A的人们会假设属性x将是django数据库字段;相反,有时它可以是静态字符串值。

这里理想的方法是什么?我真的很想实现我的第一个例子。

0 个答案:

没有答案