Classe PolyModel

Par rapport à la classe Model standard, la classe PolyModel offre davantage de flexibilité dans la définition de modèles, permettant à une application d'accepter les requêtes polymorphes. Une requête générée à partir d'une classe dérivée de PolyModel peut renvoyer des résultats constitués d'instances de la classe ou de l'une ou l'autre de ses sous-classes.

Ce type de requête est défini dans google.appengine.ext.ndb.polymodel. L'exemple ci-dessous illustre la flexibilité offerte par la 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)

La requête Contact.query() renvoie les instances de Person et de Company. Si Contact était dérivé de Model au lieu de PolyModel, chaque classe aurait une valeur kind différente et la requête Contact.query() ne renverrait pas d'instances des sous-classes de Contact.

Si vous souhaitez ne récupérer que les instances de Person, utilisez la requête Person.query(). Vous pouvez également choisir Contact.query(Contact.class_ == 'Person').

En plus des méthodes Model habituelles, la méthode PolyModel propose certaines alternatives intéressantes :

  • _get_kind() : nom de la classe racine, par exemple, Person._get_kind() == 'Contact'. La classe racine, "Contact" dans cet exemple, peut remplacer cette méthode de façon à utiliser un autre nom en tant que type ("kind") utilisé dans le datastore (pour toute la hiérarchie racine associée).
  • _class_name() : nom de la classe actuelle, par exemple, Person._class_name() == 'Person'. Une classe feuille, "Person" dans notre exemple, peut remplacer cette méthode pour utiliser un autre nom en tant que nom de classe et dans la clé de la classe. Une classe non-feuille peut aussi remplacer cette méthode, mais attention : ses sous-classes doivent également la remplacer, sinon elles utiliseront toutes le même nom de classe et vous serez vite perdu.
  • _class_key() : liste de noms de classes indiquant la hiérarchie. Par exemple, Person._class_key() == ['Contact', 'Person']. Pour les hiérarchies plus profondes, cela inclut toutes les bases entre PolyModel et la classe actuelle, y compris cette dernière, à l’exclusion du PolyModel lui-même. Identique à la valeur de la propriété class_. Son nom dans le datastore est "class".

Etant donné que le nom de la classe est utilisé dans la propriété class_ et que cette propriété est utilisée pour distinguer les sous-classes, les noms de classe (tels que renvoyés par _class_name()) doivent être uniques parmi ces sous-classes.

Cette page vous a-t-elle été utile ? Évaluez-la :

Envoyer des commentaires concernant…

Environnement standard App Engine pour Python 2