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 entrePolyModel
e 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.