根据函数的返回值设置字段选项

时间:2015-03-05 04:52:04

标签: 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

如果我派生自此类,则field_a生成的SQL在该字段旁边没有NOT NULL。我想这样做,因为我希望派生类能够覆盖is_a_null

如果我放置null=False而不是函数调用,则生成的SQL会按预期在字段旁边显示NOT NULL

2 个答案:

答案 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的情况下执行此操作会很好。