[Grok-dev] Re: Using POST request
Uli Fouquet
uli at gnufix.de
Tue Mar 25 09:59:45 EDT 2008
Hi there,
Martijn Faassen wrote:
> Uli Fouquet wrote:
> [snip: ':action' form fields require appropriate methods]
> I'm trying to understand the reasoning here. Why would a view named
> file_upload be required in order to process this field? What would be
> trying to access this file_upload view? There's after all only a single
> multipart/form-data POST request being made - do you think setuptools is
> sending another request?
No, sorry for being unclear. The whole request is handled by an
'file_upload' method/view/callable - if it exists 'inside' an 'eggs'
object. I meanwhile tried my example from the last post and it works.
> Perhaps zope's publisher machinery somehow fails badly on something in
> this form, and as a result an exception gets raised that inadvertantly
> is translated into a 404 error. The 'name=":action"' bit looks pretty
> weird, though you'd think you'd simply get a request.form[':action']
> field as a result.
The ``:action`` field is in fact the reason for the strange behaviour. I
digged a bit deeper, to understand what's happening here.
As you know, you can tell the publisher to treat form fields specially
using a '<key>:<type>' syntax. Such you can send a form field named
``myval:int`` to get myval as an integer (and not a string).
Similarily you can tell the publisher to let the request be processed by
a certain method using ``<name-of-method>:action`` syntax. I'm sure, you
already knew that, but for the archives and other people that get stuck
with strange 'action' fields behaviour, I might explain that in detail.
The code in ``zope.publisher.browser.BrowserRequest.__processItem()``::
def __processItem(self, item):
"""Process item in the field storage."""
# [...]
key = item.name
# [...]
while key:
pos = key.rfind(":")
key, type_name = key[:pos], key[pos + 1:]
# [...]
# find the right type converter
c = get_converter(type_name, None)
if c is not None:
converter = c
flags |= CONVERTED
# [...]
elif (type_name == 'method' or type_name == 'action'):
if key:
self.__meth = key
else:
self.__meth = item
# [...]
This code is executed, before the traverser starts and ``__meth`` will
be appended to the traverser path. So in an HTML-form you such can say::
<input type="hidden" name=":action" value="myhandler" />
(note the leading colon in the name attribute) or::
<input type="hidden" name="myhandler:action" />
to let the posted request be handled by a `myhandler` method.
Now, given we have an object 'eggs' which should normally handle the
request and which is reachable vie URL `localhost:8080/eggs`, we now,
with the ':action' field set to 'file_upload' let the traverser look for
'eggs/file_upload' instead of just 'eggs'. You send the request to
`localhost:8080/eggs` but the traverser will in fact look for
`localhost:8080/eggs/file_upload`, find nothing and return a 404.
With the appropriate view (i.e. one that is named 'file_upload') you can
handle this. But what about REST now?
Hope that helps.
Kind regards,
--
Uli
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 191 bytes
Desc: Dies ist ein digital signierter Nachrichtenteil
Url : http://mail.zope.org/pipermail/grok-dev/attachments/20080325/0b1132c0/attachment.bin
More information about the Grok-dev
mailing list