Reputation: 181
While storing ndb.Polymodel superclasses as an ndb.StructuredProperty, I was unable to access subclass methods; superclass methods were called instead and raising NotImplementedError's. Here is an abridged version of what I am trying to accomplish.
class Recipient(polymodel.PolyModel):
name = ndb.StringProperty()
def PrettyPrinting(self):
raise NotImplementedError, 'Rawr'
class ShippingRecipient(Recipient):
address_line_one = ndb.StringProperty()
#there are other properties, but they aren't necessary here.
def PrettyPrinting(self):
return 'Hey, this should be called.'
class LocalRecipient(Recipient):
distribution_location = ndb.StringProperty()
#same deal, more attributes, but useless for this example.
def PrettyPrinting(self):
return 'Hey this should be called.'
class Shipment(ndb.Model):
recipient = ndb.StructuredProperty(Recipient)
Now say that I have saved a shipment and stored a ShippingRecipient into the shipment's recipient field. In the datastore, the shipment recipient.class == ['Recipient', 'ShippingRecipient']. When I call:
shipment = Shipment.get_by_id('some_key')
shipment.recipient.PrettyPrinting()
The NotImplementedError is raised instead of the ShippingRecipient implementation of PrettyPrinting(...). I want the subclass method to be called when accessing the shipment's recipient field. Is there a way I can get to the subclass method instead? I know that saying the structured property is of type Recipient causes the superclass method to be called, but then maybe I don't fully understand why they would store the subclass in the recipient.class attribute.
Upvotes: 0
Views: 302
Reputation: 12986
I don't believe this can work. It will only store Recipient instances.
If you look at how PolyModel works, all variants are stored as the base class,
in your example Recipient
. It also stores the sub class names, when and entity it is retrieved from the data store, it recreates the specific subclass.
I really doubt they would have built this mechanism into StructuredProperty instantiation, and you have found this to be the case.
Upvotes: 1