[Grok-dev] Containers with different object types and traversal

Leonardo Rochael Almeida leorochael at gmail.com
Fri Mar 27 15:14:20 EDT 2009


Hi Steve,

Please keep the conversation in the list.

The subcontainers should be instances of (subclasses of)
grok.Container, and traversal should just work after you add it to the
"performance" container, just like it does for instances of Model
subclasses.

Without looking at your code it's a little difficult to know what went
wrong in your case.

Cheers, Leo

On Fri, Mar 27, 2009 at 16:02, Steve Schmechel <steveschmechel at yahoo.com> wrote:
>
> How do you get these subclasses to play nice with traversal?
> Do the __parent__ and __name__ fields need to be set manually?
>
> The application gives me a "page not found" and, when I try to inspect the objects using the Grok Admin UI, I get:
>
> http://localhost:8080/docgrok-obj/band/2009-03-15/musicians/@@inspect.html
> ...
> TypeError: ('Not enough context information to get parent', <music.musician.Musicians object at 0x36ce2a8>)
>
> Thanks,
> Steve
>
> --- On Fri, 3/27/09, Leonardo Rochael Almeida <leorochael at gmail.com> wrote:
>
>> From: Leonardo Rochael Almeida <leorochael at gmail.com>
>> Subject: Re: [Grok-dev] Containers with different object types and traversal
>> To: steveschmechel at yahoo.com
>> Cc: grok-dev at zope.org
>> Date: Friday, March 27, 2009, 12:23 PM
>> Hi Steve,
>>
>> It seems to me that the simplest way to accomplish what you
>> want is to
>> put two (subclasses of) Containers inside your Performance
>> instance,
>> called "musicians" and "songs". Inside
>> each of these sub-containers
>> you would then place, respectively, your musician and song
>> instances.
>>
>> You could use either the __init__ of your Performance class
>> or a
>> subscriber to ObjectAddedEvent that matched against your
>> Performance
>> instance to create your sub-folders.
>>
>> This would give you the URLs you wish.
>>
>> Cheers, Leo
>>
>> On Fri, Mar 27, 2009 at 13:05, Steve Schmechel
>> <steveschmechel at yahoo.com> wrote:
>> >
>> > I know I once saw a complete list of rules for default
>> traversal, but I can not seem to find it again.  Does
>> anyone know where a list like that can be found?
>> >
>> > I thought that traversal included looking for fields
>> within an object that could be traversed.  For example, an
>> object with a field that is a container of other objects
>> could be traversed as:
>> >
>> /AppContainer/ObjectName/ContainerField/ContainedObjectName
>> >
>> > Which would be handy if you had an object that had two
>> fields that were containers of different sets of objects:
>> >
>> /AppContainer/ObjectName/OtherContainerField/OtherContainedObjectName
>> >
>> > However, as I sure most of you know, this does not
>> work by default.  It seems that to contain anything that is
>> traversable (without employing a custom traverser), you need
>> to use grok.Container.
>> >
>> > I'll admit that it is taking me a while to get
>> used to using containers as content objects with their own
>> fields.  Maybe, I have spent too much time with relational
>> databases and other object models where containers (data
>> tables, collections, dictionaries, etc.) and the stuff they
>> contain (data rows, simple objects, etc.) are worked with
>> very differently.
>> >
>> > So, I finally saw some documentation on traversal of
>> nested containers (on the Repoze.bfg site).  Of course,
>> this makes sense to me when I think about a Plone site with
>> a folder that contains another folder.  But, in Plone, the
>> folder was just a folder and you couldn't add much
>> direct content except by specifying another object to be the
>> default view that "covers up" the folder's
>> URL.
>> >
>> > I was happy to find that grok.Container objects work
>> fine with schemas and autoforms.  It seems I just need to
>> dump all of my various content types into one parent
>> container.  As long as the keys do not collide, this should
>> work.
>> >
>> > I do have some questions about this arrangement.
>> >
>> > How to I keep the key string from conflicting?  I do
>> not want to create contrived names that end up in the URL.
>>  What kind of schemes to people use to keep the different
>> types of objects from colliding?  (I'm not specifically
>> talking about the "NameChooser" concept, although
>> it may play into the solution.)
>> >
>> > Example:
>> >
>> > I have a container object that represents a musical
>> performance by a band.  It has a list of songs that will be
>> performed and a set of musicians that will be playing that
>> day.  I want to be able to have something like:
>> >
>> > /SpecificPerformance/musicians/BrianWilson as the url
>> of a model object that defines a musician object and the
>> instrument being played at that performance.
>> >
>> > Now, if the band in playing a song called
>> "BrianWilson" (BNL fans will get this reference
>> ;-), I would have:
>> > /SpecificPerformance/songs/BrianWilson as the url of a
>> model object that defines a song and it's arrangement
>> and key for this performance.
>> >
>> > Now, if these are going to be in the same container I
>> need a way to tell them apart.  Do I do something with the
>> keys like:
>> > /Performance/musicians-BrianWilson
>> > /Performance/songs-BrianWilson
>> > This seems kind of ugly.
>> >
>> > Do I have to use something like z3c.Traverser to get
>> the URL back to the original form, but leave the keys as
>> above?
>> >
>> > Can I subclass grok.Container and an add another
>> dictionary and expect traversal to still work?
>> >
>> > There seems to be something close to this in the tests
>> for zope.traversing at:
>> >
>> http://svn.zope.org/zope.traversing/trunk/src/zope/traversing/tests/test_traverser.py?rev=96010&view=auto
>> >
>> > Where:
>> >
>> >    def testTraversingDictSeesDictAPI(self):
>> >        adict = {
>> >            'foo': 'bar',
>> >            'anotherdict':
>> {'bar': 'foo'},
>> >            'items': '123',
>> >            }
>> >        tr = Traverser(adict)
>> >
>>  self.assertEqual(tr.traverse('items'),
>> adict.items)
>> >
>>  self.assertEqual(tr.traverse('anotherdict/bar'),
>> 'foo')
>> >
>>  self.assertEqual(tr.traverse('anotherdict/items'),
>> >
>> adict['anotherdict'].items)
>> >
>> > It looks like, if you had another dictionary in the
>> object, you could traverse to that also.  This would
>> basically accomplish what I wanted to do in the first place,
>> but by modifying a component rather than simply arranging
>> them in a particular way.
>> >
>> > Has anyone done something like this?
>> >
>> > Any feedback is welcome.
>> >
>> > Thanks,
>> > Steve
>> >
>> >
>> >
>> > _______________________________________________
>> > Grok-dev mailing list
>> > Grok-dev at zope.org
>> > http://mail.zope.org/mailman/listinfo/grok-dev
>> >
>
>
>
>


More information about the Grok-dev mailing list