pythonpylonsvalidationformencode

Rerendering a Pylons form with a querystring parameter after FormEncode validation fails


My question may be the same as this, but the suggested answer didn't seem to help (or I didn't understand it correctly): Pylons FormEncode @validate decorator pass parameters into re-render action

I have a simple form that takes a required querystring (id) value, uses that as a hidden form field value, and validates the posted data. The controller looks like this:

class NewNodeForm(formencode.Schema):
  parent_id = formencode.validators.Int(not_empty = True)
  child_name = formencode.validators.String(not_empty = True)

def newnode(self, id):
  c.parent_id = id
  return render('newnode.html')

@validate(schema=NewNodeForm(), form='newnode')
def createnode(self):
  parentId = self.form_result.get('parent_id')
  childName = self.form_result.get('child_name')
  nodeId = save_the_data(parentId, childName)
  return redirect_to(controller = 'node', action = 'view', id = nodeId)

and the form is very basic:

<form method="post" action="/node/createnode">
  <input type="text" name="child_name">
  <input type="hidden" value="${c.parent_id}" name="parent_id">
  <input name="submit" type="submit" value="Submit">
</form>

Everything works fine if the validation passes, but if it fails, newnode can't be called because id isn't passed back. It throws TypeError: newnode() takes exactly 2 arguments (1 given). Simply defining as newnode(self, id = None) gets around this problem, but I can't do that as the id is required by the logic.

This seems so simple, but what am I missing?


Solution

  • If you are using an id arg in your newnode my preference would be to use the same arg in it's related createnode function. Adapt your post url to use an id, and you wont need to hidden the parent_id because it is now part of the url.

    <form method="post" action="/node/createnode/${request.urlvars['id']}">
      <input type="text" name="child_name">
      <input name="submit" type="submit" value="Submit">
    </form>