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/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 > > > > > 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.