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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 [email protected].
> >> To unsubscribe from this group, send email to
> >> [email protected]<google-appengine%[email protected]>
> >> .
> >> 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 [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