Ohh, after some thinking, how about this:
Basically This is a Coutable Mixin wich replaces the .count() method
on objects by caching the value in a seperate table.
code below or (http://dpaste.com/hold/92118/ for more convinient reading)
[ tried this in the SDK console]

kindest regards,
 Moritz

PS: it is important to have the mixin order... e.g. all db.Model
deriving classes before the db.Model class.


from google.appengine.ext import db

class _Counter(db.Model):
  """
  some helper class, to keep track
  of the actual amount of elements
  """
  count = db.IntegerProperty(default=0)

class Countable(db.Model):
  """
  the ``mixin'' to make an object have
  a cheap ``.count()'' method
  """

  def count(klass):
      return _Counter.get_or_insert('class:%s' % klass.__name__).count
  count = classmethod(count)
  def put(self,*args,**kwargs):
    if not self.is_saved():
      counter = _Counter.get_or_insert('class:%s' % self.__class__.__name__)
      counter.count += 1
      counter.put()
    super(Countable, self).put(*args,**kwargs)

  def delete(self, *args, **kwargs):
    counter = _Counter.get_by_key_name('class:%s' % self.__class__.__name__)
    if not counter is None:
      counter.count -= 1
      counter.put()
    super(Countable, self).delete(*args,**kwargs)

class Test(Countable, db.Model):
  name = db.StringProperty()

print "set up"
print "======"
print "  installing 10 entities in Test model..."
for i in range(10):
  Test(name='item %d' % i).put()
print "test"
print "===="
print "  Test.count() yields ", Test.count()
print "  deleting two entities"
for e in Test.all().fetch(2):
  e.delete()
print "  Test.count() yields ", Test.count()
print "tear down"
print "========="
print "  deleting all items from Test model..."
for e in Test.all():
  e.delete()
print "  deleting all items from _Counter model..."
for e in _Counter.all():
  e.delete()


On Wed, Nov 19, 2008 at 11:18 PM, Robin B <[EMAIL PROTECTED]> wrote:
>
> Have you tried having ModelMixin inherit from PropertiedClass
> directly:
>
> class ModelMixin(PropertiedClass):
>  pass
>
> class Commentable():
>  __metaclass__ = ModelMixin
>
> I am using something similar without error.
>
> Robin
>
> On Nov 19, 8:07 am, Adam <[EMAIL PROTECTED]> wrote:
>> Not that anyone cares, but the metaclass approach did not work, as
>> Python doesn't want to have two non-identical metaclasses in an
>> inheritance chain.  Or something.
>>
>> On Nov 18, 10:42 am, Adam <[EMAIL PROTECTED]> wrote:
>>
>> > It just occurred to me that this solution could be made much easier by
>> > using a simple, small metaclass (which, it is worth noting, I totally
>> > copped from GAE's PropertiedClass metaclass):
>>
>> > class ModelMixin(type):
>> >   def __init__(cls, name, bases, dct):
>> >     super(PropertiedClass, cls).__init__(name, bases, dct)
>>
>> >     for attr_name in dct.keys():
>> >       attr = dct[attr_name]
>> >       if isinstance(attr, Property):
>> >         cls._properties[attr_name] = attr
>>
>> > class Commentable():
>> >   __metaclass__ = ModelMixin
>>
>> >   comments_counter = db.IntegerProperty(required=True, default=0)
>>
>> > Bada-bing.  Now, the ugly nonsense of creating the _properties dict
>> > and assigning to it is gone.
> >
>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Google App Engine" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/google-appengine?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to