[Web-SIG] Form field dictionaries

Ian Bicking ianb at colorstudy.com
Fri Oct 24 15:11:54 EDT 2003


On Friday, October 24, 2003, at 01:00 PM, David Fraser wrote:
> Ian Bicking wrote:
>> Every time I have encountered an unexpected list it has been because 
>> of a bug somewhere else in my code.  I might use a getone() method 
>> that threw some exception when a list was encountered, but I'd 
>> *never* want to use getfirst().  getfirst() is sloppy programming.  
>> (getlist() is perfectly fine though)
>
> There seems to be a lot of agreement on this...
> So let's take it that the interface will be a dictionary, with an 
> extra method defined, getlist, which will return multiple items if 
> multiple items were defined, or a list containing a single item 
> otherwise.

Additionally, getlist should return the empty list if the key isn't 
found, as this follows naturally (but a KeyError for normal access when 
a value isn't found).  I also think cgi's default of throwing away 
empty fields should not be supported, even optionally.


But I haven't really heard reaction to the idea that you get a 
BadRequest or other exception if you try to get key that has multiple 
values.  Throwing information away is bad, and unPythonic (though very 
PHPish).  I don't think we should copy PHP here.  I have *never* 
encountered a situation where throwing away extra values found in the 
query is the correct solution.  Either the form that is doing the 
submission has a bug, or else the script needs to figure out some 
(explicit!) way to handle the ambiguity.

We also need a way to get at the raw values.  I suppose you could do:

fields = {}
for key in req.fields.items():
     v = req.getlist(key)
     if len(v) == 1: fields[key] = v[0]
     else: fields[key] = v

But that's kind of annoying, since the request object probably contains 
this kind of dictionary already.  This will be required for backward 
compatibility, if we want this request to be wrapped to support 
existing request interfaces.

As long as we're thinking about type information, there's also file 
uploads.  cgi makes them look like normal fields, but at considerable 
expense to the overall API (always using .value).  Everyone else puts 
the file-like objects into the variable, so you might end up testing:

val = req['somefield']
try:
     val = val.read()
except AttributeError:
     pass

Most of the time this isn't required, as you will seldom get a file 
upload from a source where you don't expect it.  But though less 
common, it's the same basic issue as the list issue.

--
Ian Bicking | ianb at colorstudy.com | http://blog.ianbicking.org




More information about the Web-SIG mailing list