Hey Karl, you can do that too, I made this filter earlier, and with
your example you would pass almost the same values as you have there:

foo.bar: '1'
foo.bar: '2'
foo.bar: '3'
baz : '4'

result = { 'foo' : {'bar' : ['1', '2', '3']}, 'baz' : '4'} }

Although I'm not as sure as to how you would make a validation schema
for that as easily, but once again it will be easy to access the values
in javascript with a documents.my_form['foo.bar'][0], [1], [2], etc.

### Code below
##############

class BuildTreeFilter(BaseFilter):
    """
    Will build a tree for request params with periods in the name,
    for an example look at _buildTree().
    """

    def beforeMain(self):
        cherrypy.request.paramMap =
self._buildTree(cherrypy.request.paramMap)

    def _buildTree(self, oldDict):
        """
        Given a dictionary with keys like 'foo.bar.joo', this will
return a new tree
        with a key of foo = { 'bar': {'joo' : oldValue}}, for every
key.

        Example:
        >>> print _buildTree({'company': 'Unexistential Inc',
                             'names.firstName': ['Joe', 'Boe', 'Moe'],
                             'names.lastName': ['Smith', 'Myth',
'Keith'],
                             'phone': '555-8980'})
        >>> {'company': 'Unexistential Inc',
             'names': {'firstName': ['Joe', 'Boe', 'Moe'],
                       'lastName': ['Smith', 'Myth', 'Keith']},
             'phone': '555-8980'}
        """

        stack = []
        y = {}
        for key, value in oldDict.iteritems():
            splitList = key.split(".", 1)
            if len(splitList) > 1: #there was a period in the key
                firstLevel = splitList[0]
                secondLevel = splitList[1]
                firstValue = y.get(firstLevel)

                if firstValue:
                    if type(firstValue) != dict:
                        y[firstLevel] = {}
                    y[firstLevel].update({secondLevel : value})
                else:
                    y[firstLevel] = {secondLevel : value}
                    stack.append( firstLevel ) #add to stack only once
            else:
                y[key] = value

        for i in iter(stack):
            y[i] = self._buildTree( y[i] )
            
        return y

Reply via email to