La clase PolyModel
permite que una aplicación defina modelos que admitan consultas polimórficas de una manera más flexible que la clase Model
estándar.
Una consulta producida a partir de una clase PolyModel
puede tener resultados que son instancias de la clase o de cualquiera de sus subclases.
Se define en google.appengine.ext.ndb.polymodel
. El ejemplo siguiente muestra la flexibilidad proporcionada por la clase 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()
muestra las instancias de Person
y Company
; si Contact
derivara de Model
en lugar de PolyModel
, cada clase tendría un kind
diferente y Contact.query()
no mostraría instancias de subclases apropiadas de Contact
.
Si deseas recuperar solo instancias Person
, usa Person.query()
. También puedes usar Contact.query(Contact.class_ == 'Person')
.
Además de los métodos normales de la clase Model, PolyModel posee algunos métodos de clase interesantes:
_get_kind()
: el nombre de la clase raíz, comoPerson._get_kind() == 'Contact'
. La clase raíz, Contact en este ejemplo, puede anular este método para usar un nombre diferente como el tipo usado en el almacén de datos (para toda la jerarquía cuya raíz está aquí)._class_name()
: es el nombre de la clase actual, comoPerson._class_name() == 'Person'
. Una clase hoja, Person en nuestro ejemplo, puede anular este método para usar un nombre diferente como el nombre de clase y en la clave de clase. Una clase hoja diferente también puede anular este método, pero ten en cuenta lo siguiente: sus subclases también deberían anularlo o, de lo contrario, todas usarán el mismo nombre de clase, y pronto te confundirás mucho._class_key()
: es una lista de nombres de clase que proporcionan la jerarquía. Por ejemplo,Person._class_key() == ['Contact', 'Person']
. Para jerarquías más profundas, esto incluirá todas las bases entrePolyModel
y la clase actual, incluida esta última, pero sin incluir la clase PolyModel. Es igual al valor de la propiedadclass_
. Su nombre de almacén de datos es 'class'.
Dado que el nombre de la clase se usa en la propiedad class_
y esta propiedad se usa para distinguir entre las subclases, los nombres de clase (como los muestra _class_name()
) deben ser únicos entre esas subclases.