[Web-SIG] Random thoughts
Ian Bicking
ianb at colorstudy.com
Mon Nov 3 15:53:00 EST 2003
On Nov 3, 2003, at 2:29 PM, Gregory (Grisha) Trubetskoy wrote:
> On Mon, 3 Nov 2003, Ian Bicking wrote:
>
>> On Nov 3, 2003, at 9:07 AM, Gregory (Grisha) Trubetskoy wrote:
>>>
>>> request.form(query_overrides=1) <-- returns both
>>> request.form.postdata()
>>> request.form.querydata()
>>
>> Seems a little long-winded. How about request.formdata, .postdata,
>> .querydata, where .formdata is postdata+querydata? (In practice most
>> people use the combined version)
>
> I'd say -1 on postdata and querydata, because request.postdata sounds
> to
> me like the body of the POST and querydata sounds like the "stuff after
> question mark". The word "form" has to be in there.
Sure, I don't actually like the *data names that much. Another name
might be "field" -- I think in some contexts field is clearer, because
"form" has some other concepts associated with it (method and action
being the most obvious).
>> They could be proper dictionary-like objects.
>
> Of course. To elaborate on what I had in mind (the above, btw, has an
> error - form() cannot be both a method and an object):
>
> request.form() would return a mapping object (aka dictionary-like)
> containing both post and query data.
>
> [At this point I'd like to backtrack on my prior statement - query data
> should not override post data or vice versa, they should probably be
> combined, just like they would if there were multiple form inputs by
> the
> same name - so perhaps we don't even need to override option at all]
I generally agree, but the implementation would be easier if one
overrides the other, like:
def __getitem__(self, name):
try:
return self.query[name]
except KeyError:
return self.post[name]
But otherwise:
def __getitem__(self, name):
if self.query.has_key(name):
value = self.query[name]
if self.post.has_key(name):
postvalue = self.post[name]
if isinstance(value, list):
if isinstance(postvalue, list):
return value + postvalue
else:
return value + [postvalue]
else:
if isinstance(postvalue, list):
return [value] + postvalue
else:
return [value, postvalue]
else:
return value
else:
return self.post[name]
It's not *that* bad, but it's a little annoying. At least it's
complete (i.e., information neither hidden nor lost). So I think the
less-than-elegant implementation isn't so bad. After all, it could be
the simpler:
def __getitem__(self, name):
value = self.query.getlist(name) + self.post.getlist(name)
if not value:
raise KeyError, "..."
elif len(value) == 1:
return value[0]
else:
return value
> In case of POST, availability of form data implies that something
> consumes
> (reads) the request. Some people would prefer to read it themselves. A
> (first) call to form() would trigger this action, after which there
> wouldn't be anything to read. Otherwise you could read it with
> request.read().
I forget how exactly cgi works right now, Webware has tried to get this
right but I'm not sure if it has. I think it consumes the request body
if it's valid data that can be parsed (maybe even in spite of the
content-type of the request), but otherwise leaves it intact and sets
no fields.
If it is valid data that can be parsed into fields, maybe it's not so
bad if the body is lost, because all the information remains. If you
have an option to keep the data, I'd just include it in the constructor
-- parsing it lazily (and thus throwing away the body lazily) seems
error-prone. If it can't be parsed into fields, then certainly it
should be available in some other form.
--
Ian Bicking | ianb at colorstudy.com | http://blog.ianbicking.org
More information about the Web-SIG
mailing list