Base class for class hierarchies supporting polymorphic queries.
Use this class to build hierarchies that can be queried based on
their types.
Example:
Consider the following model hierarchy:
+------+
|Animal|
+------+
|
+-----------------+
| |
+------+ +------+
|Canine| |Feline|
+------+ +------+
| |
+-------+ +-------+
| | | |
+---+ +----+ +---+ +-------+
|Dog| |Wolf| |Cat| |Panther|
+---+ +----+ +---+ +-------+
This class hierarchy has three levels. The first is the 'root
class'. All models in a single class hierarchy must inherit from
this root. All models in the hierarchy are stored as the same
kind as the root class. For example, Panther entities when stored
to the datastore are of the kind 'Animal'. Querying against the
Animal kind will retrieve Cats, Dogs and Canines, for example,
that match your query. Different classes stored in the root
class' kind are identified by their class key. When loaded from
the datastore, it is mapped to the appropriate implementation
class.
Polymorphic properties:
Properties that are defined in a given base class within a
hierarchy are stored in the datastore for all subclasses only.
So, if the Feline class had a property called 'whiskers', the Cat
and Panther enties would also have whiskers, but not Animal,
Canine, Dog or Wolf.
Polymorphic queries:
When written to the datastore, all polymorphic objects
automatically have a property called 'class' that you can query
against. Using this property it is possible to easily write a
query against any sub-hierarchy. For example, to fetch only
Canine objects, including all Dogs and Wolves:
Canine.query()
The 'class' property is not meant to be used by your code other
than for queries. Since it is supposed to represents the real
Python class it is intended to be hidden from view. (Although if
you feel the need, it is accessible as the 'class_' attribute.)
Root class:
The root class is the class from which all other classes of the
hierarchy inherits from. Each hierarchy has a single root class.
A class is a root class if it is an immediate child of PolyModel.
The subclasses of the root class are all the same kind as the root
class. In other words:
Animal.kind() == Feline.kind() == Panther.kind() == 'Animal'
Note:
All classes in a given hierarchy must have unique names, since
the class name is used to identify the appropriate subclass.