Welcome, guest | Sign In | My Account | Store | Cart

Rather than using Python's cgi.FieldStorage class, a simple dictionary is enough for 99% of CGI scripts. This recipe shows you how to convert a FieldStorage object into a simple dictionary.

Python, 16 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#!/usr/bin/python

import cgi

def cgiFieldStorageToDict( fieldStorage ):
   """Get a plain dictionary, rather than the '.value' system used by the cgi module."""
   params = {}
   for key in fieldStorage.keys():
      params[ key ] = fieldStorage[ key ].value
   return params

if __name__ == "__main__":
   dict = cgiFieldStorageToDict( cgi.FieldStorage() )
   print "Content-Type: text/plain"
   print
   print dict

Install the above script into your cgi-bin directory as 'cgitest.py', then go to http://your-server/cgi-bin/cgitest.py?x=y You should see a simple dictionary printed in response: {'x': 'y'}

The FieldStorage system is necessary when your HTML form contains multiple fields with the same name, or when people can upload files to your script, but if all you have is a simple set of uniquely-named controls, a plain dictionary is easier (and more Pythonic!) to work with.

3 comments

Graham Ashton 21 years, 1 month ago  # | flag

Alternative implementation? Nice idea. Would it be more pythonic to sublcass FieldStorage to create (e.g. SimpleFieldStorage) and implement it such that each form parameter is an attribute? You could then say

field = SimpleFieldStorage()
print "Hello %s" % field.firstname

instead of

print "Hello %s" % field['firstname']

I admit, it's splitting some hairs, and I've never done any CGI in python so I've no experience of the FieldStorage class either. Just wondering what people think...

Richie Hindle (author) 21 years, 1 month ago  # | flag

Re: Alternative implementation? The reason I use a plain dictionary is that dictionaries are totally generic and fit in well with many other Python constructs. For instance, taking your example a stage further, it's more intuitive to write this:

print "Hello %(firstname)s %(lastname)s of %(town)s" % dict

than

print "Hello %s %s of %s" % ( field.firstname, field.lastname, field.town )

One of the things I do with CGI parameters is plug them into SQL queries using exactly that construct (plus a bit of quoting for security).

d aol 14 years, 11 months ago  # | flag

Handling extrange URLs. I have watch your script, and test it on a server (im starting), anyway

It does not handle things like http://localhost/mycgi/simple.py?x=que&x=y&a&b&c=/

The code ignore all, except values of the form a=y, but repetitions of a=1&a=2&a=3 are ignored, also &a&b&c are ignored.

Aparently is enought to check if it is a list, the crash (that show in the server) is solved.

def cgiFieldStorageToDict( fieldStorage ):
   """Get a plain dictionary, rather than the '.value' system used by the cgi module."""
   params = {}
   for key in fieldStorage.keys():
      if type(fieldStorage[key]) I have watch your script, and test it on a server (im starting), anyway

It does not handle things like http://localhost/mycgi/simple.py?x=que&x=y&a&b&c=/

The code ignore all, except values of the form a=y, but repetitions of a=1&a=2&a=3 are ignored, also &a&b&c are ignored.

Aparently is enought to check if it is a list, the crash (that show in the server) is solved.


<pre>
def cgiFieldStorageToDict( fieldStorage ):
   """Get a plain dictionary, rather than the '.value' system used by the cgi module."""
   params = {}
   for key in fieldStorage.keys():
      if type(fieldStorage[key])

</pre>