app/polymodel/__init__.py
author Pawel Solyga <Pawel.Solyga@gmail.com>
Tue, 30 Sep 2008 16:53:30 +0000
changeset 216 aac174b902b3
parent 204 7075c27170f2
permissions -rw-r--r--
Change _readonly_field_as_table_row <td> tag class names to match those used in _field_as_table_row. That should actually go into previous commit. Patch by: Pawel Solyga Review by: to-be-reviewed
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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