2

I have a form that submits data to the server that looks like the following:

videos[0][type]=Vimeo&
  videos[0][moments][0][time]=11&
  videos[0][moments][0][lng]=111&
  videos[0][moments][0][lat]=111&
  videos[0][moments][1][time]=222&
  videos[0][moments][1][lng]=222&
  videos[0][moments][1][lat]=222&
videos[1][type]=YouTube&
  videos[1][moments][0][time]=111&
  videos[1][moments][0][lng]=111&
  videos[1][moments][0][lat]=111
...

I am using Flask and I would like to be able to loop through the videos and moments but it seems like there isn't a way to do that. I tried looking for libraries on Google but my Google-fu is weak tonight.

Any suggestions? Thanks!

EDIT: Based on lazy1's answer, I modified his/her code to

def add(root, path, value):
  for part in path[:-1]:
    root = root.setdefault(part, {})
  root[path[-1]] = value

def parse(s):
  items = {}
  for key, value in parse_qsl(s):
    parts = filter(None, re.split('[\[\]]', key))
    name = parts[0]
    if name not in items: 
      items[name] = {}
    add(items[name], parts[1:], value)
  return items

that will generate a hash:

{'map': {'title': 'orange'}, 'videos': {'1': {'moments': {'0': {'lat': '111', 'lng': '111', 'time': '111'}}, 'type': 'YouTube'}, '0': {'moments': {'1': {'lat': '222', 'lng': '222', 'time': '222'}, '0': {'lat': '111', 'lng': '111', 'time': '11'}}, 'type': 'Vimeo'}}}

for a query that looks like:

map[title]=orange&
videos[0][type]=Vimeo&
  videos[0][moments][0][time]=11&
  videos[0][moments][0][lng]=111&
  videos[0][moments][0][lat]=111&
  videos[0][moments][1][time]=222&
  videos[0][moments][1][lng]=222&
  videos[0][moments][1][lat]=222&
videos[1][type]=YouTube&
  videos[1][moments][0][time]=111&
  videos[1][moments][0][lng]=111&
  videos[1][moments][0][lat]=111
...

2 Answers 2

3

You can use urlparse.parse_qsl to get the query parameters. However you'll need manually to construct the video objects.

Example implementation can be:

def add(root, path, value):
    for part in path[:-1]:
        root = root.setdefault(part, {})
    root[path[-1]] = value

def parse(s):
    videos = {}
    for key, value in parse_qsl(s):
        parts = filter(None, re.split('[\[\]]', key))
        insert(videos, parts[1:], value)
    return videos
Sign up to request clarification or add additional context in comments.

Comments

2

If you use formencode and can change the format of your keys to:

map.title=orange&
videos-0.type=Vimeo&
  videos-0.moments-0.time=11&
  videos-0.moments-0.lng=111&
  videos-0.moments-0.lat=111&
  videos-0.moments-1.time=222&
  videos-0.moments-1.lng=222&
  videos-0.moments-1.lat=222&
videos-1.type=YouTube&
  videos-1.moments-0.time]=111&
  videos-1.moments-0.lng]=111&
  videos-1.moments-0.lat]=111

You can use:

from urlparse import parse_qsl
from formencode.variabledecode import variable_decode

def parse(s):
   return variable_decode(parse_qsl(s))

To give:

{
 'map': {'title': 'orange'}, 
 'videos': [ 
   {
     'moments': [ {'lat': '111', 'lng': '111', 'time': '11'}, 
                  {'lat': '222', 'lng': '222', 'time': '222'}],
     'type': 'Vimeo'
    }, {
    'moments': [ {'lat': '111', 'lng': '111', 'time': '111'} ],

    'type': 'YouTube'
   }
 ]
}

1 Comment

Thanks! I think I will be using that library. I don't like the format of the names but I guess I can live with it. :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.