Python 基于函数返回值设置字段选项
我有以下抽象类:Python 基于函数返回值设置字段选项,python,django,django-models,Python,Django,Django Models,我有以下抽象类: 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 如果我从该类派生,则为字段生成的SQL_a在该字段旁边没有notnull。我希望这样做,因为我希望派生类能够重写is\u a\u null 如
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
如果我从该类派生,则为字段生成的SQL_a
在该字段旁边没有notnull
。我希望这样做,因为我希望派生类能够重写is\u a\u null
如果我将函数调用改为
null=False
,则生成的SQL会像预期的那样在字段旁边显示notnull
。不幸的是,您的方法不起作用
属性和描述符的“魔力”发生在它们作为属性访问时。例如,如果您直接引用它们,在类定义过程中,您只会得到一个属性
对象
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
类属性测试(对象):
@财产
def为空(自身):
返回错误
打印(是否为空)
打印(布尔值(为空))
真的
>>>PropertyTest()为空
假的
因此,您正在将is_a_null
属性对象传递给CharField
的构造函数,在那里它的计算结果为True
即使它按照您的意愿访问属性的getter,继承仍然不起作用。子类只是继承已经定义的字段;你永远也不能指望它会重新进入你的财产
如果Django的模型继承允许重新定义字段,那么只需在子类定义中创建一个新的field\u
属性即可。不幸的是,目前还不可能实现这一点(尽管这增加了很快将添加此功能的可能性)
您可以在该线程中修改补丁,或者从头开始创建您自己的元类,尽管这两种解决方案都有点复杂。我最终遵循了本文中的答案。例如:
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
如果有一种方法可以在不访问
\u meta
的情况下实现这一点,那就太好了。你能试试这个方法吗:null=is_a_null.fget(is_a_null)很抱歉,这做了一些不同的事情。对于常规方法来说似乎也是如此。我不知道我为什么要用房子。