Google Code предлагается на следующих языках: English – Español – 日本語 – 한국어 – Português – Pусский – 中文(简体) – 中文(繁體)
Класс PolyModel является суперклассом для определения моделей данных, которые, в свою очередь, могут быть суперклассами для определения других моделей данных. Запросы, выполняемые из класса PolyModel, могут возвращать экземпляры класса и любых его подклассов.
PolyModel входит в модуль google.appengine.ext.db.polymodel.
PolyModel является подклассом класса Model и наследует его методы класса и экземпляра. Класс PolyModel переопределяет некоторые методы класса Model, но не содержит каких-либо новых элементов интерфейса.
Нередко бывает полезно определять модели данных в виде классификационной иерархии, так же как в базе данных объектов один класс объектов может быть определен как подкласс другого. Такая база данных может выполнять запросы к объектам родительского класса, включая в результаты объекты его подклассов. Хранилище данных App Engine не поддерживает такой тип запросов по умолчанию, но его можно реализовать с помощью механизма, имеющегося в SDK Python, класса PolyModel.
Класс модели, полученный из класса PolyModel, может быть базовым для других классов моделей. Запросы, создаваемые для таких классов с помощью методов all() и gql(), включают экземпляры подклассов в свои результаты.
В подклассах можно определять новые свойства, отсутствующие в родительских классах. Однако переопределять свойства родительских классов в подклассах нельзя. (Это приведет к возникновению ошибки DuplicateProperty.)
Рассмотрим простой пример из статьи Объекты и модели. Обратите внимание, что класс PolyModel предоставляется в пакете google.appengine.ext.db.polymodel.
from google.appengine.ext import db
from google.appengine.ext.db import polymodel
class Contact(polymodel.PolyModel):
phone_number = db.PhoneNumberProperty()
address = db.PostalAddressProperty()
class Person(Contact):
first_name = db.StringProperty()
last_name = db.StringProperty()
mobile_number = db.PhoneNumberProperty()
class Company(Contact):
name = db.StringProperty()
fax_number = db.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.all():
# Returns both p and c.
# ...
for person in Person.all():
# Returns only p.
# ...
В отличие от Expando, класс PolyModel не поддерживает динамические свойства. Эквивалента PolyModel для Expando не существует.
Полиморфизм не является естественной функцией хранилища данных. Вместо этого полиморфизм реализован в самом классе PolyModel. Все объекты, созданные из подклассов PolyModel, сохраняются в хранилище данных с тем же типом, который является названием корневого класса (например, Animal). Каждый объект сохраняет иерархию своих классов в виде свойства 'class' с несколькими значениями. Когда приложение создает запрос с помощью методов all() или gql() класса PolyModel, в этот запрос добавляется фильтр по свойству 'class', ограничивающий результаты объектами, созданными из класса и его подклассов.
Поскольку для хранения информации о классах PolyModel использует свойство объекта, индексы для полиморфических запросов должны содержать свойство 'class'. Подразумеваемый фильтр является фильтром равенства, и его можно комбинировать с фильтрами равенства и неравенства по другим свойствам.
Примечание. Класс PolyModel использует в свойстве 'class' только названия классов, а не полные пути. Можно создавать иерархии классов с несколькими узлами, имеющими одинаковые названия, например A → B и A → C → B. Запрос к одной из них вернет объекты из обеих. Аналогичным образом, запросы A → B → C и A → C → B функционально являются идентичными. Не рекомендуется создавать узлы с одинаковыми названиями в одной иерархии классов.
Конструктор класса PolyModel определяется следующим образом:
Класс модели, который может являться суперклассом для других классов моделей и запросы которого могут возвращать в качестве результатов экземпляры его подклассов. Как и для класса Model, для класса PolyModel необходимо создать подкласс, чтобы задать тип объектов данных.
PolyModel является подклассом класса Model и наследует или переопределяет его методы.
Аргументы:
Название нового объекта. Это название становится частью первичного ключа. Если значение – None, то в качестве ключа используется идентификатор, созданный системой.
Значение аргумента key_name не должно начинаться с цифры или иметь форму __*__. Если приложение использует в качестве названий ключей объектов хранилища данные, передаваемые пользователем, например адрес электронной почты, сначала оно должно проверить значение на соответствие этим требованиям и скорректировать его. Для этого можно добавить к значению определенный префикс, например строку "key:".
Значение аргумента key_name хранится в виде строки Unicode, при этом значения str преобразуются в текст ASCII.
Помимо методов, определяемых классом Model, класс PolyModel обладает следующими методами:
Возвращает название класса и названия всех его родительских классов в виде кортежа.
Возвращает название класса. Класс может переопределить этот метод, если название класса Python меняется, а объектам необходимо использовать прежнее название этого класса.