Google Code offered in: English - Español - 日本語 - 한국어 - Português - Pусский - 中文(简体) - 中文(繁體)
NDB is an experimental, innovative, and rapidly changing new feature for App Engine. Unfortunately, being on the bleeding edge means that we may make backwards-incompatible changes to NDB. We will inform the community when this feature is no longer experimental.
The PolyModel
class lets an application define models
that can be superclasses for other data model
definitions. A query produced from a PolyModel
class
can have results that are instances of the class or any of its subclasses.
It is defined in google.appengine.ext.ndb.polymodel
.
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.query()
returns Person
and Company
instances;
if Contact
derived from Model
instead of from
PolyModel
, each class would have a different kind
and Contact.query()
would not return instances of
proper subclasses of Contact
.
If you wish to retrieve only Person
instances,
use 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
PolyModel
and 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 class_
property
and this property is used to distinguish between the subclasses,
the class names (as returned by _class_name()
) should be unique
among those subclasses.