I'd say the problem here is that when you use the SubfieldBase
metaclass, your field subclass acts as a descriptor for the field and
attaches itself to the model class. This exploits the fact that
regular field types don't do any special voodoo regarding model
instances.
With ForeignKeys, however, the situation is quite a lot different. In
this case the field attaches a RelatedDescriptor to the model which
handles the object accessible through the field's name and takes care
of storing the actual field's value in another attribute of the model
instance (its name with '_id' appended, hence sub_id in your example).
What happens with your code is that the SubfieldBase metaclass
overrides the RelatedDescriptor, so the value you pass here::
>>> t = Test.objects.create(sub=ts)
gets stored directly in the 'sub' attribute and 'sub_id', which is
where Django expects the raw value for ForeignKeys, is not set at all.
As for what you are doing, I don't think subclassing ForeignKeys is
the way to go. Currently they defer most of the work to their target
fields, you might try to do something similar with the features you're
trying to add.
Michal