Hi folks
After my previous post about a KeyError after a form validation failure,
I've now narrowed down the behaviour change in pylons 0.9.7 from 0.9.6, and
what might be causing it. I believe this change is incorrect. I've also
included a minimal test case to reproduce the issue.
When using the @validate decorator to validate a form submission using
formencode, validation failure causes the request to be forwarded to the
form display method specified by the 'form' argument to the decorator, as a
GET. Examining the contents of request.params in the form display method
after a validation failure, *only GET parameters* are present - none of the
POST parameters are available.
This means that a form requiring extra parameters that are still present on
validation failure must supply these as GET parameters (via the POST URL for
the form) - including them as hidden fields in the form will not work. This
is a change in behaviour from 0.9.6, where the POST parameters were still
available on validation failure.
I believe that the 0.9.6 behaviour is the correct one - the proper
parameters are those submitted by the request which were valid *when
parsed*, not those which would apply when the submit method is changed from
POST to GET later on.
It's easy to reproduce this, using a minimal controller and template based
on the Form Handling page on the Wiki. With the code below, submitting the
form at /form/form with no email address prints out:
Params from display method: UnicodeMultiDict([('avar', u'dummy')])
i.e. the parameter from the URL. Note that the hidden field from the form
isn't present.
Submitting the form again with a valid email address prints:
Params from submit method: UnicodeMultiDict([('avar', u'dummy'),
('email', u'[email protected] <u%[email protected]>'), ('submit', u'Submit'),
('hidden', u'Hidden')]).
i.e. now both the GET and POST parameters are present.
form.py:
-----------
import logging
from pylons import request, response, session, tmpl_context as c
from pylons.controllers.util import abort, redirect_to
from helloworld.lib.base import BaseController, render, validate
log = logging.getLogger(__name__)
import formencode
class EmailForm(formencode.Schema):
allow_extra_fields = True
filter_extra_fields = True
email = formencode.validators.Email(not_empty=True)
class FormController(BaseController):
def form(self):
print 'Params from display method:', request.params
return render('/form.mako')
@validate(schema=EmailForm(), form='form')
def email(self):
print 'Params from submit method:', request.params
return 'Your email is: %s' % self.form_result.get('email')
form.mako:
---------------
${h.form(h.url_for(action='email', avar='dummy'), method='post')}
Email Address: ${h.text('email')}
${h.submit('submit', 'Submit')}
${h.hidden('hidden', 'Hidden')}
${h.end_form()}
Cheers ................................................. John Dickson
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"pylons-discuss" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/pylons-discuss?hl=en
-~----------~----~----~----~------~----~------~--~---