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)很抱歉,这做了一些不同的事情。对于常规方法来说似乎也是如此。我不知道我为什么要用房子。