Unfortunately your approach is not going to work.
The "magic" of properties and descriptors happens when they are accessed as attributes. If you refer to them directly—for instance, during the class definition—you just get a property
object.
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
So, you are passing the is_a_null
property object to the constructor for CharField
, where it evaluates as True
.
Even if it was accessing the property's getter as you desire, that still wouldn't work with inheritance. The subclass simply inherits the already-defined field; you could never count on it re-acccessing your property.
If Django's model inheritance allowed for redefining fields, you could simply create a new field_a
attribute in the subclass definition. Unfortunately, that is not currently possible (though this discussion raises the possibility that this feature will soon be added).
You could adapt the patch in that thread, or create your own metaclass from scratch, though those will both be somewhat complex solutions.