PolyModel class lets an application define models
that can be superclasses for other data model
definitions. A query produced from a
can have results that are instances of the class or any of its subclasses.
It is defined in
from google.appengine.ext import ndb from google.appengine.ext.ndb import polymodel class Contact(polymodel.PolyModel): phone_number = ndb.PhoneNumberProperty() address = ndb.PostalAddressProperty() class Person(Contact): first_name = ndb.StringProperty() last_name = ndb.StringProperty() mobile_number = ndb.PhoneNumberProperty() class Company(Contact): name = ndb.StringProperty() fax_number = ndb.PhoneNumberProperty() p = Person(phone_number='1-206-555-9234', address='123 First Ave., Seattle, WA, 98101', first_name='Alfred', last_name='Smith', mobile_number='1-206-555-0117') p.put() c = Company(phone_number='1-503-555-9123', address='P.O. Box 98765, Salem, OR, 97301', name='Data Solutions, LLC', fax_number='1-503-555-6622') c.put() for contact in Contact.query(): print 'Phone: %s\nAddress: %s\n\n' % (contact.phone_number, contact.address)
Contact derived from
Model instead of from
PolyModel, each class would have a different
Contact.query() would not return instances of
proper subclasses of
If you wish to retrieve only
Person.query(). You could also use
Contact.query(Contact.class_ == 'Person').
In addition to the regular Model methods, PolyModel has some interesting class methods:
_get_kind(): the name of the root class; e.g.
Person._get_kind() == 'Contact'. The root class, Contact in this example, may override this method to use a different name as the kind used in the datastore (for the entire hierarchy rooted here).
_class_name(): the name of the current class; e.g.
Person._class_name() == 'Person'. A leaf class, Person in our example, may override this method to use a different name as the class name and in the class key. A non-leaf class may also override this method, but beware: its subclasses should also override it, or else they will all use the same class name, and you will soon be very confused.
_class_key(): a list of class names giving the hierarchy. For example,
Person._class_key() == ['Contact', 'Person']. For deeper hierarchies, this will include all bases between
PolyModeland the current class, including the latter, but excluding PolyModel itself. This is the same as the value of the
class_property. Its datastore name is 'class'.
Since the class name is used in the
and this property is used to distinguish between the subclasses,
the class names (as returned by
_class_name()) should be unique
among those subclasses.