我有以下抽象类:
class BaseClass(models.Model):
@property
def is_a_null(self):
return False
field_a = models.CharField(max_length=1, null=is_a_null)
class Meta:
abtract = True
如果我派生自此类,则field_a
生成的SQL在该字段旁边没有NOT NULL
。我想这样做,因为我希望派生类能够覆盖is_a_null
。
如果我放置null=False
而不是函数调用,则生成的SQL会按预期在字段旁边显示NOT NULL
。
答案 0 :(得分:0)
不幸的是,你的方法不起作用。
属性和描述符的“魔力”在作为属性访问时发生。如果您直接引用它们 - 例如,在类定义期间 - 您只需获得一个property
对象。
class PropertyTest(object):
@property
def is_a_null(self):
return False
print(is_a_null)
print(bool(is_a_null))
<property object at 0x02C0D5A0>
True
>>> PropertyTest().is_a_null
False
因此,您将is_a_null
属性对象传递给CharField
的构造函数,其值为True
。
即使它正在按照您的意愿访问该属性的getter,仍然无法继承。子类只是继承已经定义的字段;你永远不能指望它重新占领你的财产。
如果Django的模型继承允许重新定义字段,则可以在子类定义中创建一个新的field_a
属性。不幸的是,目前还不可能(尽管this discussion提出了很快就会添加此功能的可能性。)
您可以在该线程中修改补丁,或者从头开始创建自己的元类,尽管这些都是一些复杂的解决方案。
答案 1 :(得分:0)
我最终在这个question中听到了答案。例如:
class BaseClass(models.Model):
field_a = models.CharField(max_length=1)
class Meta:
abtract = True
class DerivedClass(BaseClass):
pass;
DerivedClass._meta.get_field('field_a').null = True
如果有办法在不访问_meta
的情况下执行此操作会很好。