author | Sverre Rabbelier <srabbelier@gmail.com> |
Sun, 12 Oct 2008 16:47:39 +0000 | |
changeset 306 | ba39e8992709 |
parent 204 | 7075c27170f2 |
permissions | -rw-r--r-- |
203
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
1 |
# |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
2 |
# Copyright (c) 2008 Andreas Blixt <andreas@blixt.org> |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
3 |
# Project homepage: <http://code.google.com/p/blixt/> |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
4 |
# |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
5 |
# License: MIT license <http://www.opensource.org/licenses/mit-license.php> |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
6 |
# |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
7 |
|
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
8 |
"""Data-related Google App Engine extensions. |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
9 |
""" |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
10 |
|
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
11 |
from google.appengine.ext import db |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
12 |
|
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
13 |
import sys |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
14 |
|
204
7075c27170f2
Add ModelWithFieldAttributes *before* PolyModel, so that everything does not
Todd Larsen <tlarsen@google.com>
parents:
203
diff
changeset
|
15 |
# Add ModelWithFieldAttributes *before* PolyModel, so that everything does |
7075c27170f2
Add ModelWithFieldAttributes *before* PolyModel, so that everything does not
Todd Larsen <tlarsen@google.com>
parents:
203
diff
changeset
|
16 |
# not become a "ModelWithFieldAttributes" in the Datastore. |
7075c27170f2
Add ModelWithFieldAttributes *before* PolyModel, so that everything does not
Todd Larsen <tlarsen@google.com>
parents:
203
diff
changeset
|
17 |
from soc.models import base |
7075c27170f2
Add ModelWithFieldAttributes *before* PolyModel, so that everything does not
Todd Larsen <tlarsen@google.com>
parents:
203
diff
changeset
|
18 |
|
203
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
19 |
class Error(Exception): |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
20 |
"""Base of all exceptions in the blixt.data module.""" |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
21 |
pass |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
22 |
|
204
7075c27170f2
Add ModelWithFieldAttributes *before* PolyModel, so that everything does not
Todd Larsen <tlarsen@google.com>
parents:
203
diff
changeset
|
23 |
class PolyModel(base.ModelWithFieldAttributes): |
203
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
24 |
"""An extension to Google App Engine models that improves the support for |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
25 |
inheritance. |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
26 |
|
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
27 |
Any models extending a model that extends PolyModel will be stored in the |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
28 |
datastore as the same kind as the model that extends PolyModel, but with |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
29 |
their additional properties. When they are retrieved from the datastore, |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
30 |
they will be loaded as the appropiate model class. |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
31 |
|
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
32 |
The difference from the Model class is that queries will include models that |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
33 |
inherit from the model being queried. |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
34 |
""" |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
35 |
inheritance_line = db.StringListProperty() |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
36 |
|
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
37 |
def __init__(self, parent = None, key_name = None, _app = None, **kwds): |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
38 |
"""Creates a new instance of this polymorphic model. |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
39 |
|
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
40 |
Args: |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
41 |
parent: Parent instance for this instance or None, indicating a top- |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
42 |
level instance. |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
43 |
key_name: Name for new model instance. |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
44 |
_app: Intentionally undocumented. |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
45 |
args: Keyword arguments mapping to properties of model. |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
46 |
""" |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
47 |
if self.__class__ == PolyModel or not isinstance(self, PolyModel): |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
48 |
raise Error('Instances of PolyModel must be created through a ' |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
49 |
'subclass of PolyModel.') |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
50 |
|
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
51 |
line = [] |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
52 |
for c in self.__class__.__mro__: |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
53 |
if c == PolyModel: |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
54 |
self.__class__._kind = p |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
55 |
break |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
56 |
line.append('%s.%s' % (c.__module__, c.__name__)) |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
57 |
p = c |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
58 |
|
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
59 |
kwds['inheritance_line'] = line |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
60 |
|
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
61 |
super(PolyModel, self).__init__(parent = parent, key_name = key_name, |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
62 |
_app = _app, **kwds) |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
63 |
|
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
64 |
@classmethod |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
65 |
def _kind_type(cls): |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
66 |
"""Gets the class highest in the model inheritance hierarchy (the class |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
67 |
that will be used as the datastore kind.) |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
68 |
""" |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
69 |
p = cls |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
70 |
|
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
71 |
for c in cls.__mro__: |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
72 |
# The meta-class 'PropertiedClass' calls kind() which leads here. |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
73 |
# The variable 'PolyModel' is not assigned until after the meta- |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
74 |
# class has finished setting up the class. Therefore, a string |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
75 |
# comparison is used instead of a value comparison. |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
76 |
if c.__name__ == 'PolyModel': break |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
77 |
p = c |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
78 |
|
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
79 |
return p |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
80 |
|
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
81 |
@classmethod |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
82 |
def all(cls): |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
83 |
"""Returns a query over all instances of this model, as well as the |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
84 |
instances of any descendant models, from the datastore. |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
85 |
|
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
86 |
Returns: |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
87 |
Query that will retrieve all instances from entity collection. |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
88 |
""" |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
89 |
qry = super(PolyModel, cls).all() |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
90 |
|
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
91 |
if cls != cls._kind_type(): |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
92 |
full_name = '%s.%s' % (cls.__module__, cls.__name__) |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
93 |
qry.filter('inheritance_line =', full_name) |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
94 |
|
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
95 |
return qry |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
96 |
|
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
97 |
@classmethod |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
98 |
def from_entity(cls, entity): |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
99 |
"""Converts the entity representation of this model to an instance. |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
100 |
|
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
101 |
Converts datastore.Entity instance to an instance of the appropiate |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
102 |
class, which can be cls or any descendant thereof. |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
103 |
|
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
104 |
Args: |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
105 |
entity: Entity loaded directly from datastore. |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
106 |
|
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
107 |
Raises: |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
108 |
KindError when cls is incorrect model for entity. |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
109 |
""" |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
110 |
if entity.has_key('inheritance_line'): |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
111 |
mod_name, cls_name = entity['inheritance_line'][0].rsplit('.', 1) |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
112 |
__import__(mod_name) |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
113 |
cls = getattr(sys.modules[mod_name], cls_name) |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
114 |
return super(PolyModel, cls).from_entity(entity) |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
115 |
|
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
116 |
@classmethod |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
117 |
def kind(cls): |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
118 |
"""Returns the datastore kind we use for this model. |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
119 |
|
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
120 |
This is the name of the class that is highest up in the inheritance |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
121 |
hierarchy of this model. |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
122 |
""" |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
123 |
return cls._kind_type().__name__ |
187d45783300
Add the third-party PolyModel class. This class supports inheritance in
Todd Larsen <tlarsen@google.com>
parents:
diff
changeset
|
124 |