Python 2.7 has reached end of support
and will be deprecated
on January 31, 2026. After deprecation, you won't be able to deploy Python 2.7
applications, even if your organization previously used an organization policy to
re-enable deployments of legacy runtimes. Your existing Python
2.7 applications will continue to run and receive traffic after their
deprecation date. We recommend that
you migrate to the latest supported version of Python.
Stay organized with collections
Save and categorize content based on your preferences.
The PolyModel class lets an application define models that
support polymorphic queries, in a more flexible way than the standard Model class.
A query produced from a PolyModel derived class can have results that are instances
of the class or any of its subclasses.
It is defined in google.appengine.ext.ndb.polymodel. The following example shows
the flexibility provided by the PolyModel class.
Contact.query() returns Person
and Company instances;
if Contact derived from Model instead of from
PolyModel, each class would have a different kind
and Contact.query() would not return instances of
proper subclasses of Contact.
If you wish to retrieve only Person instances,
use Person.query(). You could also use
Contact.query(Contact.class_ == 'Person').
In addition to the regular Model methods,
PolyModel has some interesting class methods:
_get_kind(): the name of the root class;
e.g. Person._get_kind() == 'Contact'.
The root class, Contact in this example, may override
this method to use a different name as the kind used in the datastore
(for the entire hierarchy rooted here).
_class_name(): the name of the current class;
e.g. Person._class_name() == 'Person'.
A leaf class, Person in our example, may override this method to
use a different name as the class name and in the class key.
A non-leaf class may also override this method, but beware: its subclasses
should also override it, or else they will all use the same class name,
and you will soon be very confused.
_class_key(): a list of class names giving the hierarchy.
For example,
Person._class_key() == ['Contact', 'Person'].
For deeper hierarchies, this will include all bases between
PolyModel and the current class, including the latter,
but excluding PolyModel itself. This is the same as the value of the
class_ property. Its datastore name is 'class'.
Since the class name is used in the class_ property
and this property is used to distinguish between the subclasses,
the class names (as returned by _class_name()) should be unique
among those subclasses.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Hard to understand","hardToUnderstand","thumb-down"],["Incorrect information or sample code","incorrectInformationOrSampleCode","thumb-down"],["Missing the information/samples I need","missingTheInformationSamplesINeed","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-08-25 UTC."],[[["\u003cp\u003eThis page outlines the use of legacy bundled services and APIs, specifically within the first-generation runtimes of the App Engine standard environment.\u003c/p\u003e\n"],["\u003cp\u003eThe \u003ccode\u003ePolyModel\u003c/code\u003e class enables applications to define models that support polymorphic queries, allowing a query from a \u003ccode\u003ePolyModel\u003c/code\u003e derived class to return instances of the class or any of its subclasses.\u003c/p\u003e\n"],["\u003cp\u003e\u003ccode\u003ePolyModel\u003c/code\u003e provides class methods like \u003ccode\u003e_get_kind()\u003c/code\u003e, \u003ccode\u003e_class_name()\u003c/code\u003e, and \u003ccode\u003e_class_key()\u003c/code\u003e to manage class hierarchy and naming within the datastore.\u003c/p\u003e\n"],["\u003cp\u003eWhen using \u003ccode\u003ePolyModel\u003c/code\u003e, class names returned by \u003ccode\u003e_class_name()\u003c/code\u003e must be unique among subclasses to properly distinguish them within the datastore's \u003ccode\u003eclass_\u003c/code\u003e property.\u003c/p\u003e\n"]]],[],null,["# PolyModel Class\n\n| This page describes how to use the legacy bundled services and APIs. This API can only run in first-generation runtimes in the App Engine standard environment. If you are updating to the App Engine Python 3 runtime, refer to the [migration guide](/appengine/migration-center/standard/migrate-to-second-gen/python-differences) to learn about your migration options for legacy bundled services.\n\nThe `PolyModel` class lets an application define models that\nsupport polymorphic queries, in a more flexible way than the standard `Model` class.\nA query produced from a `PolyModel` derived class can have results that are instances\nof the class *or* any of its subclasses.\n\nIt is defined in `google.appengine.ext.ndb.polymodel`. The following example shows\nthe flexibility provided by the PolyModel class.\n\n\n```python\nfrom google.appengine.ext import ndb\nfrom google.appengine.ext.ndb import polymodel\n\nclass Contact(polymodel.PolyModel):\n phone_number = ndb.PhoneNumberProperty()\n address = ndb.PostalAddressProperty()\n\nclass Person(Contact):\n first_name = ndb.StringProperty()\n last_name = ndb.StringProperty()\n mobile_number = ndb.PhoneNumberProperty()\n\nclass Company(Contact):\n name = ndb.StringProperty()\n fax_number = ndb.PhoneNumberProperty()\n\np = Person(phone_number='1-206-555-9234',\n address='123 First Ave., Seattle, WA, 98101',\n first_name='Alfred',\n last_name='Smith',\n mobile_number='1-206-555-0117')\np.put()\n\nc = Company(phone_number='1-503-555-9123',\n address='P.O. Box 98765, Salem, OR, 97301',\n name='Data Solutions, LLC',\n fax_number='1-503-555-6622')\nc.put()\n\nfor contact in Contact.query():\n print 'Phone: %s\\nAddress: %s\\n\\n' % (contact.phone_number, contact.address)\n```\n\n`Contact.query()` returns `Person`\nand `Company` instances;\nif `Contact` derived from `Model` instead of from\n`PolyModel`, each class would have a different `kind`\nand `Contact.query()` would not return instances of\nproper subclasses of `Contact`.\n\nIf you wish to retrieve only `Person` instances,\nuse `Person.query()`. You could also use\n`Contact.query(Contact.class_ == 'Person')`.\n\nIn addition to the regular Model methods,\nPolyModel has some interesting class methods:\n\n- `_get_kind()`: the name of the root class; e.g. `Person._get_kind() == 'Contact'`. The root class, Contact in this example, may override this method to use a different name as the kind used in the datastore (for the entire hierarchy rooted here).\n- `_class_name()`: the name of the current class; e.g. `Person._class_name() == 'Person'`. A leaf class, Person in our example, may override this method to use a different name as the class name and in the class key. A non-leaf class may also override this method, but beware: its subclasses should also override it, or else they will all use the same class name, and you will soon be very confused.\n- `_class_key()`: a list of class names giving the hierarchy. For example, `Person._class_key() == ['Contact', 'Person']`. For deeper hierarchies, this will include all bases between `PolyModel` and the current class, including the latter, but excluding PolyModel itself. This is the same as the value of the `class_` property. Its datastore name is 'class'.\n\nSince the class name is used in the `class_` property\nand this property is used to distinguish between the subclasses,\nthe class names (as returned by `_class_name()`) should be unique\namong those subclasses."]]