Thanks PK, I'll check it out now.

Nick


On 5 March 2010 19:41, PK <p...@gae123.com> wrote:

> Hi Nick,
>
> 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.
>
> PK
> http://www.gae123.com
>
> 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/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",
> > 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
> >
> > > On 5 March 2010 08:52, Rafe <slobberch...@gmail.com> wrote:
> >
> > >>  There is currently no proper way to do "re-root" a polymodel the way
> > >> you are describing.  However, there may be a solution for your
> > >> particular problem.  I don't know enough about your actual
> > >> implementation however you might get away with simply doing a non-
> > >> Model based mix-in.  So, write your memcache utility class AS IF it
> > >> inherits from PolyModel, but don't actually allow it to do so.  Like
> > >> this:
> >
> > >>    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.
> >
> > >> On Mar 3, 7:40 pm, Nickolas Daskalou <n...@daskalou.com> wrote:
> > >> > I should state that I can set the entity kind that's saved in the
> > >> > Datastore by adding a kind() method on my "real" models, however the
> > >> > class list property of the saved entities still includes the
> "special"
> > >> > PolyModel subclass in it, and I'm not sure if that's a bad thing or
> > >> > not.
> >
> > >> > On Mar 4, 2:16 pm, Nickolas Daskalou <n...@daskalou.com> wrote:
> >
> > >> > > I've been trying to create a "special" subclass of PolyModel (that
> > >> does cool
> > >> > > stuff like update Memcache after an entity put()) which my
> polymodel
> > >> models
> > >> > > can inherit from (instead of inheriting from
> db.polymodel.PolyModel).
> >
> > >> > > This has the nasty side effect though of making that  "special"
> > >> subclass of
> > >> > > PolyModel the root class for my polymodel models.
> >
> > >> > > Is there a way around this?
> >
> > >> > > Eg. Telling db.polymodel.PolyModel to NOT include the first direct
> > >> subclass
> > >> > > in the class hierarchy that is saved to the Datastore? Or writing
> my
> > >> own
> > >> > > PolyModel by basically copying db.polymodel and changing code
> where
> > >> > > appropriate?
> >
> > >> > > Appreciate any help.
> >
> > >> > > Nick
> >
> > >> --
> > >> 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-appeng...@googlegroups.com.
> > >> To unsubscribe from this group, send email to
> > >> google-appengine+unsubscr...@googlegroups.com<google-appengine%2bunsubscr...@googlegroups.com>
> <google-appengine%2bunsubscrib...@googlegroups.com>
> > >> .
> > >> For more options, visit this group at
> > >>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-appeng...@googlegroups.com.
> To unsubscribe from this group, send email to
> google-appengine+unsubscr...@googlegroups.com<google-appengine%2bunsubscr...@googlegroups.com>
> .
> For more options, visit this group at
> http://groups.google.com/group/google-appengine?hl=en.
>
>

-- 
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-appeng...@googlegroups.com.
To unsubscribe from this group, send email to 
google-appengine+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/google-appengine?hl=en.

Reply via email to