class CoolFeature(object):
def put(self):
... clear memcache ...
super(CoolFeature, self).put()
Now define your root class:
class MyModel(CoolFeature, polymodel.PolyModel):
...
Here comes the Python lesson, so forgive me if you already know all
this ;)
The key is that you use 'super' correctly and that you have
CoolFeature be the first class your model class inherits from.
'super' allows you to traverse your objects functionality correctly
according to the python "method resolution order". You can see this
order by for any class by studying MyModel.__mro__. This indicates
the order which calls to super will traverse your class definitions.
If you do:
class A(object):
def p(self):
print 'A'
class B(object):
def p(self):
print 'B'
super(B, self).p()
class C(B, A):
def p(self):
print 'C'
super(C, self).p()
...calling C().p() will print:
C
B
A
You should be able to implement whatever functionality you need this
way. Let me know if there are issues with doing that.
--
You received this message because you are subscribed to the Google Groups "Google App Engine" group.
To post to this group, send email to google-a...@googlegroups.com.
To unsubscribe from this group, send email to google-appengi...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-appengine?hl=en.
I have been using the pattern described by Rafe very successfully in
my app. Regarding the problem you are desribing I have written up how
I solved the problem here:
http://www.gae123.com/articles/tds/model-mixin.html
Read the whole page for the details or just scroll to the bottom for
the solution that has worked for me.
On Mar 4, 10:22 pm, Nickolas Daskalou <n...@daskalou.com> wrote:
> Using non-Model mix-ins worked a treat. Thanks again Rafe.
>
> There is one small problem I'm hoping you can help me with (again). It's not
> a show-stopper because I can work around it, however I'm hoping you'd know
> of a nicer way to do this. Note that it's not only specific to PolyModel,
> but to db.Model as well.
>
> The problem is with adding extra db.* properties to these mix-ins (so that
> all subclasses that use the mix-in get these extra properties stored in the
> Datastore).
>
> Let's say I change the CoolFeature mix-in to this:
>
> class CoolFeature(object):
>
> * cool_name = db.StringProperty()*
>
> def put(self):
> self.cool_name = 'Cool ' + self.name
> super(CoolFeature, self).put()
>
> class MyModel(CoolFeature,db.Model):
>
> name = db.StringProperty()
>
> If I then create an instance of MyModel and try put()'ing it to the
> Datastore:
>
> mm = MyModel(name='blah')
> mm.put()
>
> I get this error:
>
> Traceback (most recent call last):
> ...
> File
> "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/db/__init__.py",
> line 473, in __set__
> setattr(model_instance, self._attr_name(), value)
> File
> "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/db/__init__.py",
> line 588, in _attr_name
> return '_' + self.name
> TypeError: cannot concatenate 'str' and 'NoneType' objects
>
> This error occurs both on the dev and production servers.
>
> Upon further investigation, the error occurs because the name property of
> the underlying Property superclass of the cool_name property instance is
> None. So I then changed the bold line above to:
>
> cool_name = db.StringProperty(name='cool_name')
>
> This got rid of the error being raised, however the cool_name property was
> not saved to the Datastore (only the name property was).
>
> The workaround is to add the property cool_name to each
> CoolFeaturesubclass. So it's not terribly bad, but if you know of a
> better way to
> accomplish what I'm trying to do, I'd love to hear it.
>
> Cheers,
>
> Nick
>
> On 5 March 2010 12:40, Nickolas Daskalou <n...@daskalou.com> wrote:
>
>
>
> > Thanks for your reply Rafe. Using non-Model mix-ins seems like the way to
> > go.
>
> > As with many App Engine developers, my Python experience is equivalent to
> > my App Engine experience, so I appreciated the Python lesson ;)
>
> > Nick
>
> >> google-appengi...@googlegroups.com<google-appengine%2Bunsubscribe...@googlegroups.com>
> >> .
> >> For more options, visit this group at
> >>http://groups.google.com/group/google-appengine?hl=en.- Hide quoted text -
>
> - Show quoted text -
To unsubscribe from this group, send email to google-appengi...@googlegroups.com.
http://code.google.com/appengine/articles/extending_models.html
Nice analysis PK.
As described, the main problem with your first approach was that
properties are not initialized unless they use the Propertied base
class. The problem with the Propertied base class is that it is too
tied to the actual Datastore implementation. Ideally, there would be
a less specific meta-class that simply does property initialization
which can be used by other class that do not inherit from models but
want to be mixins. This would be ideal:
class CoolFeature(db.ModelMixin):
my_prop = db.StringProperty()
class IUseCoolFeature(CoolFeature, db.Model): ...
Or what if you wanted to use it with an Expando?
class IUseCoolFeature(CoolFeature, db.Expando): ...
Learned quite a bit since releasing db.py. Expando should have been
written as a mixin in the first place.
On Mar 5, 1:31 am, Nickolas Daskalou <n...@daskalou.com> wrote:
> Cool@your solution, PK!
>
> Since db.PropertiedClass is not documented in the official docs, I'm
> assuming there's a chance that its implemented could change in future
> releases, and possibly break your code yeah?
>
> Can someone from Google please comment on whether db.PropertiedClass is
> "concrete" enough to be able to use it in such a manner as described in PK's
> article?
>
> Nick
>
> >> "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngi ne-default.bundle/Contents/Resources/google_appengine/google/appengine/ext /db/__init__.py",
> >> > line 473, in __set__
> >> > setattr(model_instance, self._attr_name(), value)
> >> > File
>
> >> "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngi ne-default.bundle/Contents/Resources/google_appengine/google/appengine/ext /db/__init__.py",
> >> > >>http://groups.google.com/group/google-appengine?hl=en.-Hide quoted
> >> text -
>
> >> > - Show quoted text -
>
> >> --
> >> You received this message because you are subscribed to the Google Groups
> >> "Google App Engine" group.
> >> To post to this group, send email to google-a...@googlegroups.com.
> >> To unsubscribe from this group, send email to
To unsubscribe from this group, send email to google-appengi...@googlegroups.com.