Class PolyModel

Class PolyModel memungkinkan aplikasi menentukan model yang mendukung kueri polimorf, dengan cara yang lebih fleksibel daripada class Model standar. Kueri yang dihasilkan dari class turunan PolyModel dapat memiliki hasil yang merupakan instance class atau salah satu subclass-nya.

Ini ditentukan dalam google.appengine.ext.ndb.polymodel. Contoh berikut menunjukkan fleksibilitas yang diberikan oleh class 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() menampilkan instance Person dan Company; jika Contact berasal dari Model, bukan dari PolyModel, setiap class akan memiliki kind dan Contact.query() tidak akan menampilkan instance subclass Contact yang tepat.

Jika Anda hanya ingin mengambil instance Person, gunakan Person.query(). Anda juga dapat menggunakan Contact.query(Contact.class_ == 'Person').

Selain metode Model reguler, PolyModel memiliki beberapa metode class yang menarik:

  • _get_kind(): nama class root; misalnya, Person._get_kind() == 'Contact'. Class root, Contact dalam contoh ini, dapat mengganti metode ini untuk menggunakan nama yang berbeda sebagai jenis yang digunakan dalam datastore (untuk seluruh hierarki yang di-root di sini).
  • _class_name(): nama class saat ini; misalnya, Person._class_name() == 'Person'. Class leaf, Person dalam contoh kita, dapat mengganti metode ini untuk menggunakan nama yang berbeda sebagai nama class dan dalam kunci class. Class non-leaf juga dapat mengganti metode ini, tetapi hati-hati: subclass-nya juga harus menggantinya, atau semuanya akan menggunakan nama class yang sama, dan segera Anda akan mulai bingung.
  • _class_key(): daftar nama class yang memberikan hierarki. Contohnya, Person._class_key() == ['Contact', 'Person']. Untuk hierarki yang lebih dalam, library ini akan mencakup semua basis antara PolyModel dan class saat ini, termasuk yang terakhir, tetapi tidak termasuk PolyModel itu sendiri. Ini sama dengan nilai properti class_. Nama datastore-nya adalah 'class'.

Karena nama class digunakan dalam properti class_ dan properti ini digunakan untuk membedakan subclass, nama class (seperti yang ditampilkan oleh _class_name()) harus unik di antara subclass.