A classe PolyModel permite que uma aplicação defina modelos que
suportam consultas polimórficas, de uma forma mais flexível do que a classe Model padrão.
Uma consulta produzida a partir de uma classe derivada pode ter resultados que são instâncias
da classe ou qualquer uma das suas subclasses.PolyModel
Está definido em google.appengine.ext.ndb.polymodel. O exemplo seguinte mostra
a flexibilidade oferecida pela 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() devolve instâncias de Person
e Company;
se Contact for derivado de Model em vez de
PolyModel, cada classe teria um kind diferente
e Contact.query() não devolveria instâncias de
subclasses adequadas de Contact.
Se quiser obter apenas instâncias de Person,
use Person.query(). Também pode usar
Contact.query(Contact.class_ == 'Person').
Além dos métodos Model normais, o PolyModel tem alguns métodos de classe interessantes:
_get_kind(): o nome da classe raiz; por exemplo,Person._get_kind() == 'Contact'. A classe raiz, Contact neste exemplo, pode substituir este método para usar um nome diferente como o tipo usado no arquivo de dados (para toda a hierarquia enraizada aqui)._class_name(): o nome da classe atual; por exemplo,Person._class_name() == 'Person'. Uma classe folha, Person no nosso exemplo, pode substituir este método para usar um nome diferente como o nome da classe e na chave da classe. Uma classe não folha também pode substituir este método, mas tenha cuidado: as respetivas subclasses também o devem substituir. Caso contrário, vão usar todas o mesmo nome de classe, e vai ficar muito confuso._class_key(): uma lista de nomes de classes que indica a hierarquia. Por exemplo,Person._class_key() == ['Contact', 'Person']. Para hierarquias mais profundas, isto inclui todas as bases entrePolyModele a classe atual, incluindo esta última, mas excluindo o próprio PolyModel. Isto é igual ao valor da propriedadeclass_. O nome do arquivo de dados é "class".
Uma vez que o nome da classe é usado na propriedade class_
e esta propriedade é usada para distinguir entre as subclasses,
os nomes das classes (conforme devolvidos por _class_name()) devem ser exclusivos
entre essas subclasses.