CherryPy Project Download

Igor Murashkin was kind enough to make a filter for making FormEncode? validation easier. See the docstring for usage and examples. This should work with CherryPy 2.1 and 2.2.

class NestedListFilter:
    """Will build a nested list for request params with periods in the
    name, for an example look at _nestedList().
    
    Given a dict of the form: {'foo.bar.joo': [oldValue1, oldValue2]}
    this will return a new tree of the form:
        {foo : [{'bar': {'joo': oldValue1}},
                {'bar': {'joo': oldValue2}}]
        }
    
    Example #1:
    >>> print self._nestedList({'company': 'Unexistential Inc',
                                'names.firstName': ['Joe', 'Boe', 'Moe'],
                                'names.lastName': ['Smith', 'Myth', 'Keith'],
                                'phone': '555-8980'})
    >>> {'company': 'Unexistential Inc',
         'names': [{'firstName': 'Joe', 'lastName': 'Smith'},
                    {'firstName': 'Boe', 'lastName': 'Myth'},
                    {'firstName': 'Moe', 'lastName': 'Keith'}],
         'phone': '555-8980'}
    
    Example #2
    >>> print self._nestedList({'misc': 'Trespassing Prohibited!',
                                'top.locations.state': ['IL', 'NY'],
                                'top.locations.zip': [48890, 21142],
                                'top.markets': ['Belmont', 'Reasan']})
    >>> {'misc': 'Trespassing Prohibited!',
         'top': [{'markets': 'Belmont',
                  'locations': {'state': 'IL', 'zip': 48890}},
                 {'markets': 'Reasan',
                  'locations': {'state': 'NY', 'zip': 21142}}
                  ]}
    """
    
    def beforeMain(self):
        cherrypy.request.paramMap = self._nestedList(cherrypy.request.paramMap)
    
    def _nestedList(self, oldDict):
        newParams = {}
        for oldKey, oldValue in oldDict.iteritems():
            if "." in oldKey:
                if not isinstance(oldValue, list):
                    oldValue = [oldValue]
                
                splitList = oldKey.split(".")
                head = splitList.pop(0)
                tail = splitList.pop()
                
                bucket = newParams.setdefault(head, [])
                for index, realValue in enumerate(oldValue):
                    if index + 1 > len(bucket):
                        bucket.append({})
                    branch = bucket[index]
                    for nestKey in splitList:
                        branch = branch.setdefault(nestKey, {})
                    branch[tail] = realValue
            else:
                newParams[oldKey] = oldValue
        return newParams

Here's a formencode schema to use with example 1:

class NameSchema(Schema)
  firstName = validators.String()
  lastName = validators.String() 

class CompanySchema(Schema): 
  company = validators.String()
  names = NameSchema() 
  phone = validators.Int()

Hosted by WebFaction

Log in as guest/cherrypy to create/edit wiki pages