La classe PolyModel consente a un'applicazione di definire modelli che
supportano query polimorfiche in modo più flessibile rispetto alla classe Model standard.
Una query generata da una classe derivata PolyModel può avere risultati che sono istanze
della classe o di una delle sue sottoclassi.
È definito in google.appengine.ext.ndb.polymodel. L'esempio seguente mostra la flessibilità fornita dalla classe 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() restituisce istanze di Person
e Company;
se Contact derivato da Model anziché da
PolyModel, ogni classe avrebbe un kind diverso
e Contact.query() non restituirebbe istanze di
sottoclassi appropriate di Contact.
Se vuoi recuperare solo le istanze Person,
utilizza Person.query(). Puoi anche utilizzare
Contact.query(Contact.class_ == 'Person').
Oltre ai normali metodi del modello, PolyModel ha alcuni metodi di classe interessanti:
_get_kind(): il nome della classe radice; ad es.Person._get_kind() == 'Contact'. La classe radice, Contact in questo esempio, può eseguire l'override di questo metodo per utilizzare un nome diverso come tipo utilizzato nel datastore (per l'intera gerarchia con radice qui)._class_name(): il nome della classe attuale; ad es.Person._class_name() == 'Person'. Una classe foglia, Person nel nostro esempio, può eseguire l'override di questo metodo per utilizzare un nome diverso come nome della classe e nella chiave della classe. Anche una classe non foglia può eseguire l'override di questo metodo, ma attenzione: le relative sottoclassi devono anche eseguire l'override, altrimenti utilizzeranno tutte lo stesso nome di classe e presto ti confonderai._class_key(): un elenco di nomi di classi che forniscono la gerarchia. Ad esempio,Person._class_key() == ['Contact', 'Person']. Per le gerarchie più profonde, verranno incluse tutte le classi base traPolyModele la classe corrente, inclusa quest'ultima, ma escluso PolyModel stesso. È uguale al valore della proprietàclass_. Il nome del datastore è "class".
Poiché il nome della classe viene utilizzato nella proprietà class_
e questa proprietà viene utilizzata per distinguere le sottoclassi,
i nomi delle classi (restituiti da _class_name()) devono essere univoci
tra queste sottoclassi.