app/polymodel/__init__.py
author Pawel Solyga <Pawel.Solyga@gmail.com>
Fri, 07 Nov 2008 22:24:01 +0000
changeset 448 075360be6743
parent 204 7075c27170f2
permissions -rw-r--r--
Fix not working former_ids. Add support for "Invalid accounts". Now when id from former_ids tries to create a profile "This account is invalid." error message is displayed. Compare emails in lower cases to prevent changing User email to the same email with different character casing (needs some more testing). Patch by: Pawel Solyga
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